Documentation Archive Developer
Search

Know the Core Objects of Your App

You develop apps using the Cocoa application environment. Cocoa presents the app’s user interface and integrates it tightly with the other components of the operating system. It provides an integrated suite of object-oriented software components packaged in two core class libraries, the AppKit and Foundation frameworks, and a number of other frameworks providing supporting technologies. Cocoa classes are reusable and extensible—you can use them as is or extend them for your particular requirements.

Cocoa makes it easy to create apps that adopt all of the conventions and expose all of the power of OS X. In fact, you can create a new Cocoa application project in Xcode and without adding any code have a functional app. Such an app is able to display its window (or create new documents) and implements many standard system behaviors. And although the Xcode templates provide some code to make this all happen, the amount of code they provide is minimal. Most of the behavior is provided by Cocoa. The code you write for your app defines its particular appearance and behavior and differentiates it from other apps.

To make a great app, you should build on the foundations Cocoa lays down for you, working with the conventions and infrastructure provided for you. To do so effectively, it's important to understand how a Cocoa app fits together.

The App Style Determines the Core Architecture

The style of your app defines which core objects you must use in its implementation. Cocoa supports the creation of both single-window and multiwindow apps. For multiwindow designs, it also provides a document architecture to help manage the files associated with each app window. Thus, apps can have the following forms (example apps are in parentheses):

  • Single-window utility app (Calculator)

    These types of apps typically handle ephemeral data or manage system processes and do not create or deal with any documents or persistent user data.

  • Single-window library-style app (iPhoto)

    These types of apps have a single window but do handle persistent user data. Sometimes single-window library-style apps are called shoebox apps. All user interaction with the app happens in a single window. Often these types of apps store user data but do not present files to users, who have no need to manually save, open, or close documents.

    Library-style apps typically do not use NSDocument objects to manage their data model. These objects are designed for multiwindow document-based apps.

  • Multiwindow document-based app (TextEdit)

    These types of apps enable users to create and edit multiple documents. Each document is displayed in its own window and each document is saved to a user-specified location in the file system.

You should choose a basic app style early in your design process because that choice affects everything you do later. The single-window styles are preferred in many cases, especially for developers bringing apps from iOS. The single-window style typically yields a more streamlined user experience, and it also makes it easier for your app to support a full-screen mode. However, if your app works extensively with complex documents, the multiwindow style may be preferable because it provides more document-related infrastructure to help you implement your app.

Both single-window and multiwindow apps can present an effective full-screen mode, which provides an immersive experience that enables users to focus on their tasks without distractions.

The Core Objects for All Cocoa Apps

Regardless of whether you are using a single-window or multiwindow app style, all apps use the same core set of objects. Cocoa provides the default behavior for most of these objects. You are expected to provide a certain amount of customization of these objects to implement your app’s custom behavior.

Using the Model-View-Controller design pattern as a template, Figure 1 shows the relationships among the core objects for the single-window app styles. The objects in this figure are separated according to whether they are part of the model, view, or controller portions of the app. As you can see from the figure, the Cocoa–provided objects constitute much of the controller and view layer for your app.

Figure 1  Key objects in a single-window app

Table 1 describes the roles played by the objects in the diagram.

Table 1  The core objects used by all Cocoa apps

Object

Description

NSApplication object

(Required) Runs the event loop and manages interactions between your app and the system. You typically use the NSApplication class as is, putting any custom app-object-related code in your application delegate object.

Application delegate object

(Expected) A custom object that you provide which works closely with the NSApplication object to run the app and manage the transitions between different application states. Your application delegate object must conform to the NSApplicationDelegate protocol.

Data model objects

Hold and manipulate content specific to your app. A banking app might store a database containing financial transactions, whereas a painting app might store an image object or the sequence of drawing commands that led to the creation of that image.

Window controllers

Load and manage a single window with its views and coordinate with the system to handle standard window behaviors. You subclass NSWindowController to manage both the window and its contents.

Window objects

Represent your onscreen windows, configured in different styles depending on your app’s needs. Most windows have title bars and borders. A window object is almost always managed by a window controller. An app can also have secondary windows, also known as dialogs and panels, that support the current document window or the main window.

A window is an instance of the NSWindow class. A panel is an instance of the NSPanel class (which is a descendant of NSWindow).

View controllers

Coordinate the loading of a single view hierarchy into your app. View controllers work together with the window controller to present the contents of a window.

In OS X (unlike in iOS), view controllers are assistants to the window controller, which is ultimately responsible for everything that goes in the window.

View objects

Define a rectangular region in a window, draw the contents of that region, handle events in that region, and lay out and manage subviews. You can layer views on top of each other to create view hierarchies.

Control objects

Represent standard system controls such as buttons, text fields, and tables. Most controls work with your code to manage user interactions with your app’s content.

You can learn more about the document architecture for Cocoa apps in Mac App Programming Guide.

Additional Core Objects for Multiwindow Apps

Unlike a single-window app, a multiwindow app uses several windows to present its primary content. The Cocoa support for multiwindow apps is built around a document-based model implemented by a subsystem called the document architecture. In this model, each document object manages its content, coordinates the reading and writing of that content from disk, and presents the content in a window for editing. All document objects work with Cocoa to coordinate event delivery, but each document object is otherwise independent of its fellow document objects.

Figure 2 shows the relationships among the core objects of a multiwindow document-based app. Many of the same objects in this figure are identical to those used by a single-window app. The main difference is the insertion of the NSDocumentController and NSDocument objects between the application objects and the objects for managing the user interface.

Figure 2  Key objects in a multiwindow document app

Table 2 describes the role of these inserted objects. (For information about the roles of the other objects in the diagram, see Table 1.)

Table 2  Additional objects used by multiwindow document apps

Object

Description

Document controller object

Creates and manages all document objects of an app. A document controller also manages many document-related menu items, such as the Open Recent menu and the open and save commands. It is an object of the NSDocumentController class.

Document object

Manages the data objects associated with a document and works with other objects to display the document contents in a window. A document object is an instance of a custom subclass of NSDocument.

The App Life Cycle and App Termination

The app life cycle is the progress of an app from its launch through its termination. Users or the operating system can launch apps. The user launches apps by double-clicking the app icon, by using Launchpad, or by opening a file whose type is currently associated with the app. The system often launches apps as part of restoring the desktop to its previous state when a user logs in.

When an app is launched, the system creates a process and all of the normal system-related data structures for it. Inside the process, it creates a main thread, sets up the main event loop, and uses it to begin executing your app’s code. As described in Integrate Your Code with the Frameworks, an app draws its initial user interface and starts handling user events, one after another, and updating the user interface in the process.

Users can terminate an app by choosing the Quit command from the application menu, but the app and the system can also work together to manage termination of apps without a user’s involvement. Cocoa supports two techniques that make the termination of an app transparent and fast:

  • Automatic termination eliminates the need for users to quit an app. Instead, the system manages app termination transparently behind the scenes, killing the underlying process for apps that are not in use to reclaim needed resources such as memory.

  • Sudden termination allows the system to kill an app’s process immediately without waiting for it to perform any final actions. The system uses this technique to improve the speed of operations such as logging out of, restarting, or shutting down the computer.

Although automatic termination and sudden termination are independent techniques, apps should generally support both. Apps must opt in to both automatic termination and sudden termination and implement appropriate support for them. They must support persistence and ensure that any user data and state is saved well before termination; if the underlying app process is then killed, the app can use the saved data and state to restore itself to where it was when it was terminated. And because the user does not quit an autoterminable app, such an app should also save the state of its user interface using the built-in Cocoa support. Saving and restoring the interface state provides the user with a sense of continuity between app launches.

OS X Apps Behave in Similar Ways

During an app’s runtime life, it behaves in ways that are similar if not identical to other OS X apps. It presents itself on the screen through its windows and views and perhaps also by drawing custom content and presenting and manipulating text. It also handles events using the same path as other apps.

An App Presents its User Interface Along with Other Apps and the System

Mac users often see on their screens an assortment of windows and views, some belonging to apps and others belonging to the system itself. The system displays the user’s desktop, the dock, the Finder, and in the menu bar any number of menu extras such as the audio volume control. An app’s user interface is made up of an app-specific menus in the menu bar, one or more windows, and one or more views.

The menu bar is a repository for commands that the user can perform in the app. The application menu bar stretches across the top of the screen, replacing the menu bar of any other app when the app is foremost. All of an app’s menus in the menu bar are owned by one NSMenu instance that’s created by the app when it starts up. Menu commands (or menu items) may apply to the app as a whole, to the currently active window, or to the currently selected object. You are responsible for defining the commands that your app supports and for providing the event-handling code to respond to them. Menu items are NSMenuItem objects.

You use windows and views to present your app’s visual content on the screen and to manage the immediate interactions with that content. Single-window apps have one main window and may have one or more secondary windows or panels. Multiwindow apps have multiple windows for displaying their primary content and may have one or more secondary windows or panels too. The style of a window determines its appearance on the screen. The windows of the system and of apps are interleaved according to specific levels and Z-order. If multiple apps currently are launched, a window of the currently active app is foremost and is shown with its controls enabled. Figure 3 shows the menu bar, along with some standard system and app windows and panels.

Figure 3  Windows and menus displayed by apps and the system

Window Programming Guide contains information about creating and configuring windows. View Programming Guide presents information about using and creating view hierarchies.

An App Handles Events Originating in User Actions

As the window server delivers events to an app, it queues those events and then processes them sequentially in its main run loop. Processing an event involves dispatching the event to the object best suited to handle it.

Distributing and handling events is the job of responder objects, which are objects inheriting from the NSResponder class. An application, its windows and views, window and view controllers, and other objects are all responder objects. An app dispatches an event to the window where it occurred. The window object, in turn, forwards the event to what is called the first responder. In the case of mouse events, the first responder is typically the view object in which the touch or click took place.

If the first responder is unable to handle an event, it forwards the event to its next responder, which is typically a parent view, view controller, or window. If that object is unable to handle the event, it forwards it to its next responder, and so on, until the event is handled. This series of linked responder objects is known as the responder chain. Messages continue traveling up the responder chain—toward higher-level responder objects, such as a window controller or the application object—until the event is handled. If the event isn't handled, it is discarded. The responder object that handles an event often sets in motion a series of programmatic actions by the app.

Cocoa Event Handling Guide provides more information about responders, the responder chain, and handling events.