Reputation: 4797
My app - a document based Core Data app - is going through a second iteration and now needs multiple windows to manage several model objects. Currently it manages Events and Locations through one window and one controller. The standard generated document class acts as controller for the main window at the moment.
I now want a separate window for managing Locations model objects. It seems good design to have a separate controller (NSWindowController) for each window, but then I realised that these controllers will not have access to the Managed Object Context, which is required to access the model objects.
What is the best approach here?
EDIT:
I followed ughoavgfhw solution as follows:
ManageLocationsController
as a subclass of NSWindowController
I open the Location window with:
ManageLocationsController *aController = [[ManageLocationsController alloc] initWithWindowNibName:@"ManageLocations"];
[aController showWindow: self];
This is done from EventDocument, which is the default class generated by XCode.
When mapping the Array Controller, this left a round black exclamation mark in the keyPath field and when I open the Location window it throws an exception saying "cannot perform operation without a managed object". Obviously not good. What am I missing?
Upvotes: 2
Views: 689
Reputation: 39915
Using custom window controllers is the best way to do this. A window controller might not have direct access to the managed object context, but it has access to the document, which does. You can access it programmatically using windowController.document.managedObjectContext
or from bindings with the key path document.managedObjectContext
. If you want to simulate direct access to the managed object context, you could create a readonly property which loads it from the document.
// header
@property (readonly) NSManagedObjectContext *managedObjectContext;
// implementation
- (NSManagedObjectContext *)managedObjectContext {
return self.document.managedObjectContext;
}
+ (NSSet *)keyPathsForValuesAffectingManagedObjectContext {
return [NSSet setWithObject:@"document.managedObjectContext"];
}
The keyPathsForValuesAffectingManagedObjectContext
method is used to tell the key-value observing system that any object observing the managedObjectContext
property should be notified of changes whenever the paths it returns change.
In order for the window controllers to work properly, they must be added to the document using addWindowController:
. If you are creating multiple windows when the document opens, then you should override makeWindowControllers
in your document method to create the window controllers, since this will be called automatically at the right time. If you are creating window controllers upon request, you can make them in whatever method you want, just be sure to add them to the document.
[theDocument addWindowController:myNewController];
As for the little black exclamation mark in IB, you will just have to ignore that. The document
property of NSWindowController
is defined with the type NSDocument
, but the managedObjectContext
property is defined by the NSPersistentDocument
subclass. IB is warning you that the property might not be there, but you know it will be so you can just ignore it.
Upvotes: 3