NSPersistentCloudKitContainer "migrate to a completely new store"?

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.


What is the proper workflow to do this?


I have come up with the following, but I believe it is wrong.

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 a while to come up with this workflow, but I still think it is wrong. Could someone give me some insight on how to properly perform a CloudKit Container Migration with NSPersistentCloudKitContainer.

Replies

So I believe I am overthinking it!



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

    // TODO: Migrate Core Data Store to new Model Version
    container.loadPersitentStores...
    ...
}()


This should be enough to handle the migration from Container 1 to 2, since the data is already stored in Core Data. Then instead of hooking up a persistent container to the old CloudKit container (which would probably throw errors due to mismatched Schema), we can use CloudKit to fetch and confirm all data has already transfered properly, fix missing data, and delete the recrods in Container 1.



I decided not to Migrate Containers for this, instead Im using "versioned entity" approach, but I just wanted to post this here in case it can help someone else. If someone uses this approach, I'd love to hear your feedback whether it worked or not.