0

I was previously instantiating a UIManagedDocument within the first view controller that appeared on screen (embedded in a navigation controller), setting the managedObjectContext as a property on each controller that needed it, and passing the context via the prepareForSegue methods. That worked, but I kept getting a periodic UIManagedDocument objective C message send error (UIManagedDOcument _setInConflict) when completely relaunching or activating the app from the background. Apparently a message was being sent to a deallocated instance of UIManagedDoc (ARC is enabled). I'm using storyboards.

After research, I saw the approach of opening or creating the UIManagedDocument in the app delegate, and just passing the context from it to the first on-screen view controller. The document itself is declared as a file-level variable in the app delegate (code below), apparently this delays the "premature deallocation" a bit. I get a context in the app delegate. That crash on relaunch has gone away, at least thus far.

The problem is I can't pass the context from the app delegate to the first initial view controller. The completion handler executes after the document is opened, but not until after I've attempted to set the app delegate's context as the initial view controller's context. I can pass to subsequent view controllers with the segue methods after I've gotten a valid context in the first view controller.

What's the proper way to wait until the document is opened and the app delegate's context has been set? I'm not sure if or how to nest completion handler blocks. The delay is very short, but it's causing the view controller's context to be set before there is one.

Also, is that code concerning the access between the root view controller (navigation controller) and my initial view controller correct? I'm asking about "nesting" completion handlers because putting it just before the RETURN statement didn't do it either.

    @implementation AppDelegate{

        UIManagedDocument *document;
    }

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // Override point for customization after application launch.

        NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        url = [url URLByAppendingPathComponent:@"Demo Document"];


        document = [[UIManagedDocument alloc] initWithFileURL:url];


        if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]]) {
            //create
            [ document saveToURL:url
                forSaveOperation:UIDocumentSaveForCreating
               completionHandler:^(BOOL success) {
                   if (success) {
                       self.context = document.managedObjectContext;
                       NSLog(@"Database Ready");


                   }
               }];
        } else if (document.documentState == UIDocumentStateClosed){
            //open
            [document openWithCompletionHandler:^(BOOL success) {
                if (success) {
                    self.context = document.managedObjectContext;
                    NSLog(@"Database Ready from Opened");
                    if (self.context) {
                        NSLog(@"got one");

   //Here is the code that's just "stuck" out of place                    
                        UINavigationController *rootNavigationController = (UINavigationController *)self.window.rootViewController;
                        InitialVC *myViewController = (InitialVC *)[rootNavigationController topViewController];
                        // Configure myViewController
                            myViewController.context = self.context;

                    }

                }
            }];

        } else {
            //try to use
            self.context = document.managedObjectContext;

        }
Tulon
  • 3,684
  • 6
  • 31
  • 50
vapul
  • 77
  • 8
  • 1
    It's possible this can help you ... http://stackoverflow.com/a/20760583/294884 – Fattie May 25 '14 at 08:02
  • 1
    But moreover it's possible THIS could help you! http://stackoverflow.com/a/23403979/294884 – Fattie May 25 '14 at 08:03
  • I'm reading through both comments, I understand the concept in the first one, but couldn't get it to work with the above code. The example uses a block that has been passed into a file, then combines it with a method, where the block executes after a set of steps are performed. As my code is in the app delegate, I don't "yet" have a block to pass in. I came up with a workaround using NSNotifications, where I set the alpha of my button that allows the user to enter info to 0; it doesn't "appear" (alpha = 1) until there's a managedObjectContext. Not the best way. Second comment is interesting. – vapul May 26 '14 at 23:24

0 Answers0