2

I've been reading this thread on Stackoverflow and have been trying to replicate the solution with no success in my own project.

My project has 4 tabs. In my app delegate I do this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    


    Page1 *page1 = (Page1 *)[navController topViewController];
    Page2 *page2 = (Page2 *)[navController topViewController];
    Page3 *page3 = (Page3 *)[navController topViewController];
    Page4 *page4 = (Page4 *)[navController topViewController];

    page1.managedObjectContext = self.managedObjectContext;
    page2.managedObjectContext = self.managedObjectContext;
    page3.managedObjectContext = self.managedObjectContext;
    page4.managedObjectContext = self.managedObjectContext;


    [self.window makeKeyAndVisible];

    return YES;
}

In the originating thread it says I need to create a IBOutlet to each navController for each tab I want to use Core data on.

Whilst you can assign multiple delegates for the UINavigationController the same is not true for the outlets, you can only ever supply ONE outlet for the navController.

I can get Page1 to work, but the other pages simply crash; because of the lack of an IBOutlet.

Do I really need X IBOutlets for Y Tabs or can I do it another way?

Another issue is that the originating thread the accepted answer is:

Ideally you want to pass either the NSManagedObjectContext, NSFetchedResultsController or the relevant NSManagedObject "down" into the UIViewController.

But there is no code or example of how to do this.

Ideally, I do not want to use a singelton or use the app delegate all over the place.

Any confirmation and clarification would be great.

Thanks.

Community
  • 1
  • 1
zardon
  • 2,910
  • 6
  • 37
  • 58

1 Answers1

2

Your immediate problem has nothing to do with Core Data. You are assigning the same navigation controller to each tab when you need a separate navigation controller for each tab otherwise the navigation controller's hierarchy of views will get scrambled every time you change tabs.

The pattern recommended in the question you linked to is called "dependency injection" and it is the one that Apple recommends in most cases. However, in the case of tabbars or any other complex view/view-controller hierarchy, dependency injection can get to complicated. It's a particular issue with tabbars because you don't usually load all tab view/view-controllers when the app starts but wait until each tab is selected before loading its elements.

Instead, you can use an alternative pattern that exploits the UIApplication objects singleton status. Since there is only one application object, there is only one application delegate object. That means that anywhere in the app you can make a call like this:

(MyApplicationDelegate *) appDelegate=(MyApplicationDelegate *)[[UIApplication sharedApplication] delegate];

... and always get the same application object. Then, if you have the managed object context defined as a property of the app delegate you can get the context just by:

theManagedObjectContext=appDelegate.managedObjectContext

Add these two lines to every view controller and you can always be sure of getting the app delegate's managed object context.

TechZen
  • 64,370
  • 15
  • 118
  • 145
  • Hello there. Thank you for your answer. Just some clarification. Am I right in thinking you need to create a seperate navigation outlet or controller for each tab? As for the appDelegate, I always thought using this was bad practice for core data. I'm going to try 2 ideas. 1. Create 4 IBOutlets for each tab. 2. Create 4 different Navigation controllers for each tab? Or I could just avoid all of that and just use your idea of using the appDelegate – zardon May 27 '11 at 10:35
  • It seems you are right, having the appDelegate in each of the tabs is not only easier, it doesn't lose the context. Thanks! – zardon May 30 '11 at 20:23