I have an iPhone application that has a MainWindow.xib holding a UITabBarController, which in turn has a UINavigationController and a custom UIViewController subclass in its ViewControllers array. The root view controller for the UINavigationController and the custom view controller are both loaded from other xib files.
The app uses core data, the stack is initialized in the app delegate (as per the convention).
The app delegate adds the UITabBarController to the window:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Configure and show the window
[window addSubview:[tabBarController view]];
[window makeKeyAndVisible];
}
I realize that I need to propagate a pointer to the ManagedObjectContext created in the app delegate, but I don't know how to proceed (even reading all the good commentary on the topic here and here):
I guess I don't understand well enough how to work with the UITabBarController.
Ideally you want to pass either the NSManagedObjectContext
, NSFetchedResultsController
or the relevant NSManagedObject
"down" into the UIViewController
. This allows the "parent" to control the "child" and determine what the child should have. This creates a more loosely coupled design and allows you to easily re-arrange UIViewController
instances as needed. It also makes it easier to reuse a UIViewController
.
In a tab view design it is no different. Your AppDelegate passes the NSManagedObjectContext
to whoever is responsible for creating the initial UIViewController
instances that go into the UITabBarController
. In turn that creator passes the relevant information (NSManagedObject
, NSFetchedResultsController
, and/or NSManagedObject
instances) into the UIViewController
instances as it is constructing them.
If you want to use the dependency injection method to pass the managed object context with a tab bar controller, a more robust solution would be to loop on all the view controllers in applicationDidFinishLaunching
:
for (id vc in tabBarController.viewControllers) {
[vc setManagedObjectContext:self.managedObjectContext];
}
Good, I looked long and hard at the CoreDataBooks sample application and did it like this:
Added the following code to applicationDidFinishLaunching
:
// pass the managed object context to the view controllers
RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
rootViewController.managedObjectContext = self.managedObjectContext;
mapViewController.managedObjectContext = self.managedObjectContext;
And now it works like a charm.
I've ran into this same problem, i'll share my solution.
First you need a reference to the Nav Controller in the Tab Bar in the nib file, make sure you connect it up.
IBOutlet UINavigationController *navigationController;
Then, get the Controller as recommended in the support docs and send it the managedObjectContext:
SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
saved.managedObjectContext = self.managedObjectContext;
Alex (from another post) is right, "You should generally stay away from getting shared objects from the app delegate. It makes it behave too much like a global variable, and that has a whole mess of problems associated with it."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With