3

Okay, I've tried to figure this out over and over again.

I know the best practice is to have the App Delegate pass the managed object context to the first view controller in an application, and then have each subsequent view controller pass the managed object context down. However, when I'm using a Tab Bar Controller in my application, I can seem to wrap my head around that extra layer.

The only way I've been able to figure out how to do it is have the root view controller of each tab "Reach Back" into the app delegate to grab the context, but as I understand it this is poor form.

DVG
  • 17,392
  • 7
  • 61
  • 88

4 Answers4

2

You can use interface builder to achieve the same thing.

Here is a slightly modified (for some additional clarity) version of Rog's original suggestion - notice the IBOutlet's

@interface AppDelegate : NSObject <UIApplicationDelegate> {
    ViewController1 *vc1;
    ViewController2 *vc2;
    ViewController3 *vc3;
}

@property (nonatomic, retain) IBOutlet ViewController1 *vc1;
@property (nonatomic, retain) IBOutlet ViewController2 *vc2;
@property (nonatomic, retain) IBOutlet ViewController3 *vc2;

Then on the implementation file:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
       vc1.managedObjectContext = self.managedObjectContext;
       vc2.managedObjectContext = self.managedObjectContext;
       vc3.managedObjectContext = self.managedObjectContext;
       // Continue with your implementation logic
}

Then from within Interface Builder ctrl drag from your App Delegate to the View Controller nested within the Tab Bar Controller and hook up the relevant View controller from the contextual menu that appears.

Paul.s
  • 38,494
  • 5
  • 70
  • 88
1

You can also just do something like this in your AppDelegate:

CoreDataUsingViewController *vc = (CoreDataUsingViewController *)[[tabBarController viewControllers] objectAtIndex:1];
vc.managedObjectContext = self.managedObjectContext;

I was adding coreData to an existing project with a few different build targets and didn't want to recreate all the different UITabBarControllers from scratch. It was pretty easy to do this way, though I'm not sure if it's the most artful way to do it or not.

See also

How to share a ManagedObjectContext when using UITabBarController

Community
  • 1
  • 1
Toby
  • 390
  • 4
  • 18
1

The key was, in the end, not to rely on interface builder to build the tab bar controller. By doing it manually in code I'm able to easily pass the managed object context to the view controller as I create them in applicatoinDidFinishLaunchingWithOptions:

I used this article as my basis: http://www.iphonelife.co.uk/creating-a-uitabbarcontroller-programmatically/

DVG
  • 17,392
  • 7
  • 61
  • 88
0

Not sure if I understand your issue correctly but why not simply pass the MOC to the other view controllers in the same manner? Here's an example:

@interface AppDelegate : NSObject <UIApplicationDelegate> {
    ViewController1 *vc1;
    ViewController2 *vc2;
    ViewController3 *vc3;
}

// Declare properties as per normal

Then on the implementation file:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
       vc1.managedObjectContext = self.managedObjectContext;
       vc2.managedObjectContext = self.managedObjectContext;
       vc3.managedObjectContext = self.managedObjectContext;
       // Continue with your implementation logic
}

I hope it helps! Rog

Rog
  • 18,602
  • 6
  • 76
  • 97
  • 1
    Doing it this way isn't quite solving the problem I'm having, as the UITabController instance is creating a new instance of MyCustomViewController at runtime, so setting the MOC in this manner will set it for an object that never gets used. – DVG Feb 13 '11 at 21:51
  • I am pretty sure the view controllers associated with a tab bar controller are instantiated when the tabBarController is created. Their views are loaded as needed but at `applicationDidFinishLaunching` you already have access to the view controllers to set variables as per above. Set a breakpoint in your `applicationDidFinishLaunching` method and you can verify that. – Rog Feb 13 '11 at 22:24