Archive for February, 2010

Cocoa – separate window controller for the MainWindow

February 9, 2010

Imagine you have created a Cocoa Application in XCode and started to implement your stuff in the MainWindow of the application. As you do more work this class gets bigger and bigger. A possible solution is to factor out the code responsible for the MainWindo in it’s own controller class. With a separate controller for the MainWindow of the application the AppDelegate class keeps much cleaner.
For doing this an extra nib for the MainWindow has to be created and therefor an extra WindowController, e.g. MainWindowController. The AppDelegate is now responsible for the MainMenu and has no own window. Be sure to delete the window in the MainMenu.xib file if is already contained.

On applicationDidFinishingLaunching in AppDelegate the MainWindowController has to be created and called to show it’s window.

– (void)applicationDidFinishLaunching:(NSNotification*)notification
 // load the app’s main window
 mainWindowController = [MainWindowController alloc];
 [mainWindowController setManagedObjectContext:[self managedObjectContext]];
 [mainWindowController initWithWindowNibName:@”MainWindow”];
 [mainWindowController showWindow:self];

If CoreData is being used, the MainWindowController needs access to the ManagedObjectContext. In this sample I created an extra method for setting the context.

After doing this the GUI of the MainWindow can be designed in InterfaceBuilder. The FilesOwner of the MainWindow is now the MainWindowController class and the FilesOwner of the MainMenu remains AppDelegate.
Further a connection has to be made from FilesOwner to the window, to set the window outlet. And vice versa from the window to the FilesOwner to set the delegate.

For a sample on how to create an extra controller for the MainWindow see the SourceView sample from Apple. This sample does not use CoreData.

This sceanrio is a way for single document applications. If you are creating a document based application with multiple windows, there is another approach to create the initial window controllers for the document. The method makeWindowControllers from NSDocument has to be overridden.