1

I have a model that has already been pushed to production, and I would like to move an attribute to a new entity as a relationship.

From this:

extension Note {
   @NSManaged public var drawingData: Data?
   ....
}

To This:

extension Note {
    @NSManaged public var drawing: Drawing?
    ....
}

extension Drawing {
   @NSManaged public var drawingData: Data?
   ....
}

According to the Apple Docs under the "Update your Production Schema" section, I will need to migrate to a new CloudKit Container, since we can't delete attributes on "production" CKRecords.

Migrate users to a completely new store, using NSPersistentCloudKitContainerOptions to associate the new store with a new container.

I have read all the documentation, and every blog I have been able to find on NSPersistentCloudKitContainer, but none really go into how to handle this.

Proposed Solution

I need to have 2 vars for 2 different containers, "old" and "new".

lazy var oldPersistentContainer: NSPersistentCloudKitContainer = {
   let container = NSPersistentCloudKitContainer(name: "Model")
   let storeLocation = URL(fileURLWithPath: "/path/to/cloud.store")
   let storeDescription =
        NSPersistentStoreDescription(url: storeLocation)
   // Set the container options on the cloud store
   cloudStoreDescription.cloudKitContainerOptions = 
        NSPersistentCloudKitContainerOptions(
        containerIdentifier: "com.myCompany.myApp")
   container.loadPersistentStores...
   ...
}()

/// NOTE: - `containerIdentifier` has been "bumped"
lazy var newPersistentContainer: NSPersistentCloudKitContainer = {
   let container = NSPersistentCloudKitContainer(name: "Model")
   let storeLocation = URL(fileURLWithPath: "/path/to/cloud.store")
   let storeDescription =
        NSPersistentStoreDescription(url: storeLocation)
   // Set the container options on the cloud store
   cloudStoreDescription.cloudKitContainerOptions = 
        NSPersistentCloudKitContainerOptions(
        containerIdentifier: "com.myCompany.myApp2")

   // TODO: Migrate Core Data Store if needed
   container.loadPersistentStores...
   ...
}()

NOTE: newPersistentContainer would have a "bumped" containerIdentifier and it would also perform Core Data Migration.

Then I think I would need to manually move all records from oldPersistentContainer and add them to newPersistentContainer. Once all the data has been moved into the new container , I would delete all records from oldPersistentContainer. Would that be enough in terms of cleaning up oldPersistentContainer?

It took me awhile to come up with this workflow, and I am not confident that it is the "correct" way to handle this. Is this how we're supposed to handle Container Migration with NSPersistentCloudKitContainer?

hidden-username
  • 2,610
  • 3
  • 14
  • 19
  • Hi, i did this when i was syncing my local content into the cloud. But i do have a different question: my model structure changed quite a lot and i'm not sure, how to change the scheme in the CloudKit Dashboard. Is it possible, that the new CoreData Version is automatically being migrated to Cloud Kit Developer scheme or did you have to add attributes on your own? – EMart Sep 17 '20 at 19:52

0 Answers0