Recently, I have made quite extensive changes to my schema and need to migrate my CoreData + CloudKit model to a new version. The changes require me to use a custom NSEntityMigrationPolicy
because I have a rather complex mapping between some old entities and new entities.
- I have added a new model version. Deleted some entities, and added some entities.
- I have defined the
NSEntityMigrationPolicy
withcreateDestinationInstances(forSource:in:manager:)
andcreateRelationships(forDestination:in:manager:)
. - I have created a new Core Data Mapping Model. This was probably unnecessary.
- Within the Core Data Mapping Model, I have specified Custom Policy for all entities.
- In my container setup, I added two options, as below:
storeDescription.setOption(false as NSNumber, forKey: NSMigratePersistentStoresAutomaticallyOption)
storeDescription.setOption(false as NSNumber, forKey: NSInferMappingModelAutomaticallyOption)
I mostly followed a "Core Data Heavyweight Migration" guide. I'm unable to share the link, but it can be quite easily found on the web. (It's not for CloudKit specifically.)
When I run my app, I am getting the most basic of errors, which is:
The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store.
So I guess that migration wasn't even attempted, which makes sense because I set NSMigratePersistentStoresAutomaticallyOption
to false.
I tried to go beyond what I could find on the web and attempted to manually initialize migration:
let sourceModel = container.persistentStoreCoordinator.managedObjectModel
guard let modelURL = Bundle.main.url(forResource: "MyModelName", withExtension: "xcdatamodeld") else {
fatalError("Unable to locate model file.")
}
guard let destinationModel = NSManagedObjectModel(contentsOf: modelURL) else {
fatalError("Unable to load destination model.")
}
let migrationManager = NSMigrationManager(sourceModel: sourceModel, destinationModel: destinationModel)
let mappingModel = NSMappingModel(from: [Bundle.main], forSourceModel: sourceModel, destinationModel: destinationModel)!
migrationManager.currentEntityMapping.entityMigrationPolicyClassName = "MyMigrationPolicyClassName"
I am then stuck at the migrateStore(from:type:mapping:to:type:)
method. It seems to target only local storage, not CloudKit. Otherwise, what do I provide for URLs and types?
Any guidance for custom logic CoreData with CloudKit migration would be greatly appreciated.