2

I'm trying to call the method saveToURL forSaveOperation completionHandler on a UIManagedDocument however the completion block is not executing. It fails at (1) on the first attempt to save and fails at (2) at attempts after that. I'm not sure if this means it's writing to disk the first time or not. However, NSLogs in the completionHandler are never logged at all.

- (void)useDocument
{
    CoreDataSingleton *cds = [CoreDataSingleton getInstance];
    UIManagedDocument *document = cds.document;
    NSURL *url = document.fileURL;
    if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]]) {
        NSLog(@"This is logged");
        [document saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
              NSLog(@"This is never logged");
              if (success) {
                  self.managedObjectContext = document.managedObjectContext;
              } 
          }];
            // (1) Fails here on the first go
    } else if (document.documentState == UIDocumentStateClosed) {
        NSLog(@"This is logged");
        [document openWithCompletionHandler:^(BOOL success) {
            NSLog(@"This is never logged");
            if (success) {
                self.managedObjectContext = document.managedObjectContext;
            }
        }];
            // (2) Fails here on the second go
    } else {
        self.managedObjectContext = document.managedObjectContext;
    }
}

The class that implements this is a UIViewController which is a UICollectionView's data source and delegate. When I unhook the UIViewController as the data source the completionHandler is successful and the managedObjectContext is set.

Does anyone know what the issue would be?

Lithu T.V
  • 19,955
  • 12
  • 56
  • 101
davidkohn
  • 119
  • 1
  • 10
  • My first guess would be that `document` is nil, which would explain why the first `@"This is never logged"` wouldn't print. However, it doesn't explain the second. `UIDocumentStateClosed` is 1 so that second `if` condition wouldn't be met for a nil document. – paulmelnikow Apr 19 '13 at 03:56
  • The CoreDataSingelton, document and url and are non-nil. – davidkohn Apr 19 '13 at 04:39
  • How do you call this method? Is it invoked on the main thread? If you add an NSLog at the end of useDocument it *is* printed, right? – paulmelnikow Apr 19 '13 at 22:29
  • And `document` is an instance of `UIManagedDocument`, not a subclass? – paulmelnikow Apr 19 '13 at 22:29
  • Finally, when you say "fails here", is your code raising an exception? – paulmelnikow Apr 19 '13 at 22:31
  • I'm having the same problem here where the completion block isn't always called. – Christian A. Strømmen Jun 04 '13 at 12:04
  • I had the same issue, and it turns out that I didn’t invoke the completion handler on the main thread, so dispatch_async(dispatch_get_main_queue(), ^{ }); solves it. – Alison Mar 28 '17 at 10:50

2 Answers2

3

I had this issue and it was killing me. Try checking your code for building the url. Make sure you're getting a path to the NSDocumentDirectory, not NSDocumentationDirectory, as was discovered in this post.

Community
  • 1
  • 1
Lou Valencia
  • 188
  • 2
  • 6
  • You saved my ass! My saveToURL:forSaveOperation:completionHandler: kept failing(status was NO). When I have changed my path to NSDocumentDirectory it worked. I made an autocompletion mistake. – Stefan Vasiljevic Apr 13 '14 at 08:53
1

One of the reasons that SAVETOURL is not executed is in the datamodel: set the attributes/relations to optional. For me it worked after a whole week of stress!!