iosobjective-ccore-dataiclouduimanageddocument

How to migrate an UIManagedDocument from iCloud enabled to Local Only in iOS7?


I am targeting iOS7 and I use iCloud with UIManagedDocument.

I want to migrate an UIManagedDocument from iCloud enabled to Local Only. When the document is migrated I don't want any ubiquitous content related to it in the Cloud, I want it to be 100% local.

The opposite case, to transform a Local Only UIManagedDocument in an iCloud enabled UIManagedDocument is easy, it is enough to add the two options NSPersistentStoreUbiquitousContentNameKey and NSPersistentStoreUbiquitousContentURLKey in the options dictionary and to migrate the persistent store using migratePersistentStore:toURL:options:withType:error:.

I thought that to migrate back from iCloud to Local Only it was enough to migrate the persistentStore passing nil as the options dictionary but this doesn't work:

NSPersistentStoreCoordinator *psc = self.managedDocument.managedObjectContext.persistentStoreCoordinator;
NSPersistentStore *ps = [psc.persistentStores objectAtIndex:0];

if(ps){

  NSError *error;
  [psc migratePersistentStore: ps
                        toURL: dbLocalOnlyURL
                      options: nil
                    withType: ps.type
                      error: &error];

  if(error){
    NSLog(@"Error migrating the DB to Local Only: %@", error);
  }else{
    NSLog(@"DB Migrated successfully to Local Only");
  }

 }

I get a Cocoa Error 256: The operation couldn't be completed. NSUnderlyingException=unable to open database file, NSSQLiteErrorDomain= 14.

When I try to perform the operation the Using local storage is still 1. But I also tried to this with the Using local storage: 0.

I thought it could be 'because I was trying to migrate the persistent store with the documentState=UIDocumentStateNormal, so I modified the code like this:

 [self.managedDocument closeWithCompletionHandler: ^(BOOL success){

    if(success){
      NSLog(@"Document closed succesfully. Performing the migration.");

        NSPersistentStoreCoordinator *psc = self.managedDocument.managedObjectContext.persistentStoreCoordinator;
        NSPersistentStore *ps = [psc.persistentStores objectAtIndex:0];

        if(ps){

          NSError *error;
          [psc migratePersistentStore: ps
                                toURL: dbLocalOnlyURL
                              options: nil
                             withType: ps.type
                                error: &error];

        if(error){
          NSLog(@"Error migrating the DB to Local Only: %@", error);
        }else{
          NSLog(@"DB Migrated successfully to Local Only");
        }
      }
    }else{
       NSLog(@"Error closing the document.");
    }

  }];

but I still get the error. Any hint?

Is it always preferable to close the document before migrating it?

Note 1: the migration works without errors if I migrate the persistent store to another url but what I want is the very same UIManagedDocument to migrate from iCloud to Local Only.

Note 2: I posted this question also on the Apple Developers Forum.


Solution

  • Check out this link explaining UIManagedDocument and iCloud Integration and providing details of the classes and methods involved in doing this

    Also take a look at this video showing how the app works when creating UIManagedDocuments and moving them to and from iCloud to confirm its what you are trying to achieve.