3.10 Document-Based Applications

Most applications create, manage, and edit documents. A document can be anything that stores persistent data. Moreover, these applications all duplicate common functionality, such as the ability to create new documents, open existing documents, and manage multiple open documents. Cocoa provides a multiple-document application architecture that implements most of the basic functionality shared by all document-based applications. Cocoa document-based application architecture centers on the NSDocument, NSDocumentController, and NSWindowController classes.

When developing a document-based application, most development effort is likely to be spent implementing subclasses of NSDocument; any document-based application must have at least one NSDocument subclass, but may have more (think of AppleWorks, for example). In MVC terminology, an NSDocument is a controller object; it manages a document's persistent data, and to project that data into a view. This means that minimally an NSDocument subclass must know how to load data into a form useable by the application, as well as how to store this data into a persistent form. A well-implemented document subclass also provides support for printing, undo/redo operations, and edited status tracking.

An NSDocumentController instance is the administrator of a document-based application. It is responsible for servicing user requests to create, open, and save documents. NSDocumentController serves the integral role of the document factory. NSDocument knows how to load a file's contents as the document's data, and NSDocumentController knows how to create NSDocument objects under different circumstances. For example, File New is wired to tell NSDocumentController to create an instance of the application's NSDocument subclass with no initial data. When you choose a file via File Open, you tell NSDocumentController to create an instance of the document class and load the selected file's contents into that document.

If an application has more than one NSDocument subclass (say, to support different document and data formats), NSDocumentController knows which subclass to instantiate based on the requested document type. Document types are mapped to NSDocument subclasses in the application's Info.plist. Each subclass of NSDocumentis tailored to support a different data model (i.e., file format). Instances of the document-based application architecture classes relate to one another in a multi-tier tree. At runtime, a document-based application has a single instance of NSDocumentController (accessed using the sharedDocumentController class method). This instance of NSDocumentController owns and manages zero, one, or more instances of NSDocument. Each NSDocument instance, in turn, owns and manages one or more instances of NSWindowController, which each own an instance of NSWindow. Figure 3-11 shows this arrangement.

Figure 3-11. The runtime relationship of NSDocumentController, NSDocument, NSWindowController, and NSWindow objects

In simple document-based applications, where every document has just a single window, there may be no need to implement custom NSWindowController classes. The document architecture, however, allows you to create applications where there may be different or replicated views of the same data, e.g., a 3D drawing app where different windows may contain views and controls for wire frame, rendered and points-in-space representations; or a text editor where two windows might show different parts of the same file. In this variation of MVC, two controller classes work with together: NSDocument is the data model controller, and NSWindowController is the view controller. Your NSDocument subclass should manage the data model, and one or more subclasses of NSWindowController manage the windows that present the data.

    Part II: API Quick Reference