How to pass managedObjectContext from appDelegate to first ViewController when they are navigation controller between two views

I banged my head against the keyboard for a better 3 days of research and trying to figure out how I can solve the following problem.

I have a story panel that looks like this:

Start Arrow Application Launch → to Navigation Controller → to Main View Controller.

My appDelegate creates a managedObjectContext file and populates some objects with data (for testing purposes only atm it will be removed as soon as I'm ready to integrate with an external source). This work is wonderful. Now my problem is that I don't know how I can pass the MOC from appDelegate to my first ViewController, because the navigation controller is on the way. My current code in the appDidFinish method looks like this:

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

    // Pass the managed object context to the root view controller
    MainMenuViewController *rootView = (MainMenuViewController *)self.window.rootViewController;
    rootView.managedObjectContext = self.managedObjectContext; 

    //My actual Core data setup and adding data to it, it works I've tested it.

    return YES;
     }

      

Now my code works when I change the location where the app launcher arrow in the storyboard points to my mainMenuViewController, but still I lose the navigation bar in all my views. I also know how to pass the MOC from my mainMenu to another view through - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

, but I just can't figure out how to do the initial pass from appDelegate to MainViewController due to the fact in between.

I have already searched numerous threads on this site (and others) and I found a solution for "Tabbed application" and others want me to serialize the object, but for my purposes I cannot do that, (only a few views will get the MOC, and others will pass data that one view has created and modified to be tailored for specific purposes in unique views).

Any help on this nub in iOS and Objective-C is greatly appreciated. Thank you in advance.

EDIT: The error I am getting is "Application terminated due to unmapped exception ... [UINavigationController setManagedObjectContext] unrecognized selector sent to instance ...

+3


source to share


3 answers


If you're creating a new app from the Master Detail app template in Xcode 4.3 (and 4.2 I think), with both Use Storyboard and Use Master Data checked out, you'll find in AppDelegate.m

:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
    controller.managedObjectContext = self.managedObjectContext;
    return YES;
}

      



This seems to be exactly what you are looking for. The key bit is that you can request a navigation controller for your controllers.

+10


source


If an NSManagedObjectContext was set in the AppDelegate, you will not pass it; rather, you create a link to it:

AppDelegate *appDel = [UIApplication sharedApplication].delegate;   
NSManagedObjectContext *context = appDel.managedObjectContext;

      



The type of object you are referencing with doesn't matter, just like any other kind of object between the receiving object and the AppDelegate.

+2


source


In addition to my first answer, which is essentially the same as the accepted answer, except that with my help, you can use it with or without any template (not just the split view template). I provide an answer that will answer your question even more directly, and here's how to pass the context manager object reference to the destination view controller after the segue.

This answer, like my first one (and unlike the accepted answer), assumes that you at least know where the context of managed objects is in your application, and that you have the basic skills required to create a reference to it (as opposed to the accepted answer, which suggests that you cannot use Find ... in Xcode and cannot remember how to assign a value to a pointer, e.g .:

id moc = [reference to the managed object context object that you can find]

      

Since you seem to be better at answering the template related answers, try overriding the method prepareForSegue

provided in the UIViewController subclass in the Single Application View template. Inside, you'll notice a couple of comments left by Apple.

In short, you will create a reference to the destination view controller like this:

SecondVC *vc2 = segue.destinationController;

      

Then you set the reference value of the pointer to the context variable of the managed object in the target view controller to the value of the reference point wherever the instance is created:

vc2.mbo = AppDelegate.mbo;

      

I have provided a very detailed example (with a video demo) of creating segues without storyboarding (i.e. programmatically) at:

Segue programmatic identifier

By the way, if you are having difficulty understanding the use of the AppDelegate reference in my answer, I'll explain it:

  • Apple puts a reference to the Core Data object management object in AppDelegate.h / .m whenever you create a new project using any Xcode template, and also select the Use code data check box when customizing the template. In order to use this reference throughout the application (i.e. in other .m files and therefore you don't advertise multiple instances of them), you create a global application reference for the AppDelegate, which turns out to be a UIApplication delegate, which is singleton. which makes the AppDelegate the same - by simply adding this to every implementation file where you are going to refer to the managed object context:

    import "AppDelegate.h"

    define AppDelegate ((AppDelegate *) [[UIApplication sharedApplication] delegate])

You now access the managed object context object where these two lines are added:

[AppDelegate.mbo...];

      

0


source







All Articles