title: Having to use a new NSPersistentStoreUbiquitousContentNameKey when migrating from iCloud to Local and then Local back to iCloud Again
body: <p>I have a scenario where my app currently in the App Store doesn't have iCloud enabled on it, but with the update I'm working on, iCloud will be there. The user can select whether to use iCloud right at the start of using the app as soon as it's been upgraded, and can also decide to turn this on/off within the App. </p>
  
  <p>Right now, the data migrates from the App Store version (non iCloud) to iCloud if the user selects YES to use iCloud at the start, and I can get the data to migrate from the iCloud store back to the local store if the user turns iCloud off within the app. </p>
  
  <p>However, logic would tell me that if I want to then allow the user to turn on iCloud again in the app, that it should migrate the local to the iCloud store. </p>
  
  <p>Here's the code for the initial migration from the non-iCloud to iCloud when the app is first run in the <code>App Delegate:</code></p>
  
  <pre><code>- (void)upgradeAndMigrateCoreDataToiCloud {
  
      NSLog(@"Just upgraded your app. On the next run, this does not happen again.");
  
      NSURL *storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
      NSLog(@"Current Store URL (before migration): %@", [storeURL description]);
  
      NSPersistentStore *currentStore = self.persistentStoreCoordinator.persistentStores.lastObject;
  
  URLByAppendingPathComponent:@"NewStore.sqlite"];
          NSURL *cloudURL = [self grabCloudPath:@"CloudLogs"];
          NSString *cloudStoreTitle = @"EnvyCloud";
  
  
      NSDictionary *options = @{NSPersistentStoreUbiquitousContentURLKey: cloudURL,
       NSPersistentStoreUbiquitousContentNameKey: cloudStoreTitle,                               NSMigratePersistentStoresAutomaticallyOption : @YES,
       NSInferMappingModelAutomaticallyOption : @YES};
  
      [self.persistentStoreCoordinator migratePersistentStore:currentStore toURL:storeURL options:options withType:NSSQLiteStoreType error:nil];
  
      storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
      NSLog(@"Current Store URL (after migration): %@", [storeURL description]);
  
  }
  </code></pre>
  
  <p>That works perfectly. </p>
  
  <p>Here's the code for when the user wants to turn on iCloud synching from the settings (if it was previously off at the start, or if the user turned it off and now wants to turn it back on):</p>
  
  <pre><code>- (void)iCloudHasBeenEnabledFromSettings
  {
      NSURL *iCloud = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier: nil];
  
      if ((iCloud) &amp;&amp; ([[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudOn"]))
      {
          NSLog(@"iCloud is enabled, and so we can do the migration from the local to iCloud");
          [self iCloudNotifications];
  
          NSURL *storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
          NSLog(@"Current Store URL (before migration from local to iCloud): %@", [storeURL description]);
  
          NSPersistentStore *currentStore = self.persistentStoreCoordinator.persistentStores.lastObject;
  
          NSURL *cloudURL = [self grabCloudPath:@"CloudLogs"];
          NSString *cloudStoreTitle = @"EnvyCloud";
  
          NSDictionary *options = @{NSPersistentStoreUbiquitousContentURLKey: cloudURL,
                                    NSPersistentStoreUbiquitousContentNameKey: cloudStoreTitle,                               NSMigratePersistentStoresAutomaticallyOption : @YES,
                                    NSInferMappingModelAutomaticallyOption : @YES};
  
          [self.persistentStoreCoordinator migratePersistentStore:currentStore toURL:storeURL options:options withType:NSSQLiteStoreType error:nil];
  
          storeURL = [self.persistentStoreCoordinator.persistentStores.lastObject URL];
          NSLog(@"Current Store URL (after migration from local to iCloud): %@", [storeURL description]);
      }
      else if (!(iCloud) &amp;&amp; ([[NSUserDefaults standardUserDefaults] boolForKey:@"iCloudOn"]))
  
      {
          UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"iCloud is Disabled on the Device" message:@"Do you want to turn it on now? If so, you can do this from the device Settings" delegate:self cancelButtonTitle:@"Turn OFF iCloud" otherButtonTitles:@"Settings", nil];
          [alertView show];            
      }
  }
  </code></pre>
  
  <p>The only difference here is that I'm re-calling the iCloud notifications and I have an if statement to check if iCloud is enabled on the device. </p>
  
  <p>The last <code>NSLog</code> that checks the path of the <code>storeURL</code> is where the issue is. </p>
  
  <p>In the upgrade method, the <code>storeURL</code> after the migration is:</p>
  
  <pre><code>Current Store URL (after migration): file:///var/mobile/Applications/B07684DE-F74A-4503-A7B3-CD6D82CD087D/Documents/CoreDataUbiquitySupport/mobile~F6322EC0-DA27-4EEB-A6A4-0D3EA875241B/EnvyCloud/3B2005FA-FEEE-4F90-A049-E068B35F09AA/store/Envylope.sqlite
  </code></pre>
  
  <p>Showing it's been migrated appropriately. </p>
  
  <p>In this second method though, the current store url before the migration from the local to iCloud is:</p>
  
  <pre><code>Current Store URL (before migration): file:///var/mobile/Applications/B07684DE-F74A-4503-A7B3-CD6D82CD087D/Documents/Envylope.sqlite
  </code></pre>
  
  <p><strong>Issue</strong></p>
  
  <p>The issue is that after the migration, the NSLog is still:</p>
  
  <pre><code>Current Store URL (before migration): file:///var/mobile/Applications/B07684DE-F74A-4503-A7B3-CD6D82CD087D/Documents/Envylope.sqlite
  </code></pre>
  
  <p>In this method (<code>iCloudHasBeenEnabledFromSettings</code>), if I change the <code>NSPersistentStoreUbiquitousContentNameKey</code> to have a slightly different name (previously <code>EnvyCloud</code> and changing it to for example <code>EnvyCloudNew</code>), then it works and the <code>NSLog</code> shows me the <code>CoreDataUbiquityContainer</code>. </p>
  
  <p>Surely I'm doing something wrong, or is this how it's supposed to work, that it can't use the "same" <code>NSPersistentStoreUbiquitousContentNameKey?</code></p>
  
  <p>Also, are there any issues with using a different <code>NSPersistentStoreUbiquitousContentNameKey</code>?</p>
  
  <p><strong>Update</strong></p>
  
  <p>I've been doing a lot of work on this and have a few updates to this question that I'm really hoping someone can assist with. </p>
  
  <p>If I don't change the name of the <code>NSPersistentStoreUbiquitousContentNameKey</code> and leave it the same, and if I pass an error parameter through the migration, the output error in the console is:</p>
  
  <pre><code>Error = Error Domain=NSCocoaErrorDomain Code=134080 "The operation couldn’t be completed. (Cocoa error 134080.)" UserInfo=0x15e9ae90 {NSUnderlyingException=Can't add the same store twice}
  </code></pre>
  
  <p>This makes sense that it cannot add the same store twice. </p>
  
  <p>I can workaround this by first migrating the persistentStore, and then setting <code>_persistentStoreCoordinator = nil</code> before finally adding a new persistentStore - that works, but again, that doesn't seem right to me. It doesn't make sense that I'd need to do that. Why can't I just rebuild from what's already stored in iCloud, if I choose to go back from the Local store to iCloud?</p>
  
  <p>I hope this update helps point someone to point me in the right direction.</p>
  
  <p>Any thoughts would be appreciated. </p>