Question

My project has a really ugly iCloud implementation in production today and I was planning to disable it for my next update (we don't need iCloud). Here is the approach I am taking to migrate users off of iCloud and onto a local store - the update has the iCloud entitlement removed from the app and this simple sequence of events is initiated at app launch:

If there is an iCloud store ( [[NSFileManager defaultManager] fileExistsAtPath:[legacyStoreUrl path]]

  1. load the "legacy" iCloud store
  2. Migrate the iCloud store to local store

    ([_persistentStoreCoordinator migratePersistentStore:legacyStore toURL:targetStoreUrl options:options withType:NSSQLiteStoreType error:&legacyStoreMigrationError]);

  3. delete the legacy store

    ([fileManager removeItemAtURL:legacyStoreUrl error:&legacyStoreRemovalError])

Else

  1. load (or create) the local store

This all works great - on iOS6.

When I run the same code on iOS7 to migrate the local store it appears not to find the iCloud store. I don't get any indication of error, the call to the FileManager to ask if the store is there simply returns false. I verified that the url for the store used by the upgraded app is exactly the same as the one used in the previous version. Also note that the existing version of the app runs on iOS7 without any trouble accessing iCloud store.

Any thoughts on why this might be or maybe some leads on what else to investigate?

Was it helpful?

Solution

It's happening because you removed the iCloud entitlement. Without that, you're not permitted to access the iCloud store, so the whole scheme falls apart. If this works on iOS 6, it's a bug, because you're really not supposed to get access to anything iCloud-related without the correct entitlements. With iOS 7 there are a ton of internal changes, so it's not surprising they found and fixed that.

So you'll need to put that entitlement back.

Two other details:

  • When you do the migration, make sure to set the new NSPersistentStoreRemoveUbiquitousMetadataOption to @YES in the options dictionary. Otherwise some cloud-related metadata will stick around, and that can really ruin your day later on. (You might already know this but since you didn't mention it I thought I would).
  • When you remove the cloud store, don't use that NSFileManager call. For one thing, it misses the SQLite wal and shm files. Worse than that though, it leaves all the existing iCloud transaction logs just sitting there taking up space. You'll want the new(ish) removeUbiquitousContentAndPersistentStoreAtURL:options:error method on NSPersistentStore. The options dictionary here should include the same cloud-related keys you'd use when adding an iCloud store, because that's necessary to find the transaction logs.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top