oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

The Cocoa Controller Layer
Pages: 1, 2, 3

Creating a Data Model

Establishing a solid design for a data model is an essential first step to taking advantage of the controller layer technology. The application we're going to build today is a simple book catalog, so we need to put together a Book class that will serve as our data model.

Before we get going, create a new Xcode project that is a Cocoa document-based application with whatever name you like (I called my Bibliotecha). Remember, the controller layer was released in Mac OS X 10.3, so you have to be running that or a later version of Mac OS X to follow along with this article.

The class Book will be a simple representation of a book consisting or properties such as book's title and author. A more complete and accurate representation of a book might include properties for the publisher, ISBN, publication date, and more. For simplicity's sake we'll stick with just a title and author. Create a new Objective-C class named Book, and define the following class interface in Book.h:

@interface Book : NSObject {
    NSString *_title;
    NSString *_author;
- (NSString *)title;
- (NSString *)author;

- (void)setTitle:(NSString *)title;
- (void)setAuthor:(NSString *)author;

Our Book data model class is quite simple: NSString instance variables are used to store the book's title and author. We then have accessor methods to set and get the values of each of these instance variables. The implementation of these four methods is straightforward:

@implementation Book
- (NSString *)title { return _title; }
- (NSString *)author { return _author; }

- (void)setTitle:(NSString *)title
    [_title autorelease];
    _title = [title retain];

- (void)setAuthor:(NSString *)author
    [_author autorelease];
    _author = [author retain];


For each of the "getter" methods, we simply return the value of the instance variable in question. In the setter methods we autorelease the existing value, and set the value of the instance variable to the new object after we have retained it. For a simple data model, this is all we have to do. A more complicated data model might have computed properties, or the properties may be more complex data types. For example, to more accurately represent the fact that many books have multiple authors, we might have the author property be an NSArray of Author objects with properties for first, middle, and last name.

We now have established a very simple, yet sufficient, data model for Bibliotecha. Now it's time to switch gears and move into Interface Builder, where we will do most of the work to create our interface, and connect the interface to the data model through appropriate controller objects. So, double-click on the file MyDocument.nib to open it up in Interface Builder, and let's get to work over there.

In Interface Builder

Our interface will be pretty sparse: just enough to demonstrate how the controller layer functions. It will consist of two windows. The first window consists of a table view of that lists all of the books in the catalog. In addition to the table view, there are three buttons for adding and removing records in the table, as well as for opening an inspector window. The second window is an inspector-like window that allows the user to edit detailed information about the currently selected book in the table view. In this setup, the table view window is known as the master view, as it shows all of the books stored in the catalog, and the inspector is called the detail view as it may potentially display more detailed information about a single record.

The Master Interface

Our master view table has only two columns: one for the book title, and one for the author. The interface for the main window is shown here:

Here we have a table view to display the contents of our book catalog. The Add button will add a new row to the table, and the Remove button will remove the selected row. The Get Info… button is used to open up the inspector window that shows a detailed view of the selected record.

The inspector window is simple as well. It consists of nothing more than two text fields to display the values of the two properties of an instance of Book:

If the Book class had more properties than what we gave it, then we could have arranged things so that the table view shows a subset of the properties (i.e. the most important properties such as title and author), while the detail view inspector provided fields to display every property of our data model.

Now that we have our two windows setup, let's move on to wiring up some controllers.

Configuring our NSArrayController

Cocoa controller objects exist in their own Interface Builder palette, shown below:

These three objects represent the three controllers available in Cocoa. On the left we have an instance of NSUserDefaultsController, in the middle is an NSObjectController, and at the right is NSArrayController. Since we wish to use a controller to populate and manage the contents of an NSTableView we will grab an NSArrayController; drag out an instance of NSArrayController into your nib's Instances window. We want to give it some unique name so that's it easily identified when we need to use it. To do that double-click on the object label and change the name from NSArrayController to something like Book Controller.

Next, we need to tell the controller what kind of object it will be managing. An NSArrayController needs to know the data model class it will manage so it knows how to instantiate new objects. To do this, open the Attributes inspector, and change the Object Class Name from NSMutableDictionary to Book.

Now, we need to tell Book Controller what keys are available for accessing properties of Book objects. This is done in the Keys list in the same Attributes view of the inspector. The keys you enter here are the same keys one would use to access object properties using key-value coding: author and title. At this point your NSArrayController should be configured in the following way:

Now, a quick recap of what we just did: We have created an instance of NSArrayController in our nib and named it Book controller. This will be the controller that manages the contents of the master table view. The NSArrayController is configured to work with instances of the class Book, which we indicated in the Attributes inspector. We also defined the keys that the NSArrayController will use to access properties of each instance of Book managed by the array controller. These are the same keys that one would use in key-value coding to indirectly access the instance variables of Book objects. In short, we've now defined the link between the data model and controller layer of our application. Now we need to establish the bindings between the controller and the views.

Pages: 1, 2, 3

Next Pagearrow