0

I'm (sort of) following the Stanford CS193P ios class and I'm trying to get a document context without having to pass from controller to controller. Prof Haggerty uses this method to get his context, but it doesn't work for me. I'm spelling everything correctly and I can get the context when I pass it, but not when I get it this way.
Am I missing something?? I just want to get the context for the database that I know I've created without having to pass in.s

- (void)useDemoDocument
{
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    url = [url URLByAppendingPathComponent:@"Demo Document"];
    UIManagedDocument *document = [[UIManagedDocument alloc] initWithFileURL:url];

    if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]]) {
        [document saveToURL:url
           forSaveOperation:UIDocumentSaveForCreating
          completionHandler:^(BOOL success) {
              if (success) {
                  self.managedObjectContext = document.managedObjectContext;
                  [self refresh];
              }
          }];
    } else if (document.documentState == UIDocumentStateClosed) {
        [document openWithCompletionHandler:^(BOOL success) {
            if (success) {
                self.managedObjectContext = document.managedObjectContext;
            }
        }];
    } else {
        self.managedObjectContext = document.managedObjectContext;
    }
}
CSmith
  • 13,318
  • 3
  • 39
  • 42
vboombatz
  • 409
  • 6
  • 17

2 Answers2

0

I don't think you misspelled anything, but you might have the wrong expectation of what that method is doing. The method is not returning any context. It sets the context as a class property (but only in some cases!). So after calling this method you should be able to access the self.managedObjectContext property.

However.. The method implementation is not very clean and therefore a bit dangerous. It will set the 'managedObjectContext' property only for successful scenarios. The method does not clear the self.managedObjectContext property in other cases, so in those cases it's unclear what the self.managedObjectContext is pointing to. Since the method does not provide any success status you can never trust if the managedObjectContext has been set properly.

Leijonien
  • 1,415
  • 14
  • 16
  • OK, thanks. Can you please point me in the right direction? I need to return the context that points to the database specified in the URL so I can use in other VC's without having to pass it from VC to VC. Thanks – vboombatz Nov 13 '13 at 22:27
  • Did you try to use the debugger to see which code is actually executed? – Leijonien Nov 13 '13 at 23:21
  • yes the code is executed it just doesn't return the context to the database at that location. frustrating. – vboombatz Nov 14 '13 at 01:22
  • what do you mean when you say "only in some cases". Thanks for the help. – vboombatz Nov 14 '13 at 01:23
  • If you look to the completion handlers, when success == NO, the managedObjectContext is not (re)setted, so the managedObjectContext property will keep it's old value (whatever it was). You can resolve this pretty easy by starting the method by setting self.managedObjectContext = nil; – Leijonien Nov 14 '13 at 11:00
  • Leijonien, You solved my problem! I set manageobjectContext to nil and all is well. Thanks a lot!!! – vboombatz Nov 26 '13 at 15:14
0

I had the same problem (also doing Stanford class). I've since found the solution, you can find it here iOS 7 Completion handler never gets called

OpenWithCompletionHandler is asynchronous, so the application might try to use the context even before completion handler block finishes executing. Hence, it seems like the method doesn't work. Using a run loop will solve your problem.

Community
  • 1
  • 1
user2634633
  • 509
  • 8
  • 21