Reputation: 623
I have been trying to get my head around StoryBoards for OS X -- specifically, I am trying to write a Document-based app using Core Data.
I cannot figure out how to give the various View Controllers in the StoryBoard access to the NSPersistentDocument's managedObjectController.
Prior to StoryBoards, if you make a Document-based app using Core Data, you get a XIB file, with a window whose owner was the Document. The Document has an array of window controllers, but the owner of that XIB was the Document. You can add an NSArrayController, bind its Managed Object Context to the owner's Managed Object Context, and everything is fine.
If instead you make the project using StoryBoards, the top level window is owned by a NSWindowController. Where is the NSPersistentDocument? It gets created, but I cannot see where or why.
Also, in that initial storyboard you get with the template, that window has no incoming arrow, to say that it's the entry point. If you delete the window controller and add a new one, it HAS an arrow. And NOW, you will two TWO WINDOW CONTROLLERS -- the one made by the storyboard, and the one made by the Document, which creates it in its makeWindowControllers method
- (void)makeWindowControllers {
// Override to return the Storyboard file name of the document.
[self addWindowController:[[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"Document Window Controller"]];
}
Is this a bug? Clearly there's something I'm not understanding.
Upvotes: 4
Views: 189
Reputation: 73
I've been investigating the same thing, and discovered a few things so far. Some people suggest having the controller looking back up through the hierarchy to get the application delegate when not doing a document based app, but Apple recommends pushing the information out to the controllers. With a NSPersistentDocument application, I'm trying the approach of achieving this with the following code in the makeWindowControllers() method in the document class.
(windowController.window?.contentViewController as! MyViewController).moc = managedObjectContext
This assumes an appropriate property called moc in the view controller (of class MyViewController) which is the first one in the hierarchy. You could also use the represented object to store this property. You can implement a didSet method for your property to pass it down to other controllers if you wish.
Unfortunately I'm still working out the details of this approach as the above method is called after the controller's viewDidLoad() and the moc won't have been set, which also seems to mean that the array controller's Prepares Content fires too early.
Normally I wouldn't submit such an incomplete answer to your question, but did so due to there being an absence of an authoritative solution.
Upvotes: 2