9

I tried to migrate my CoreData-Model (with CloudKit) and it duplicated all of the objects I had stored. How can I correctly migrate when using CoreData with CloudKit?

Summary

I am using CoreData with CloudKit. A few days ago, I made some changes to my model and therefore needed to migrate. This is how it went (see below for details):

  1. I just made the changes in my model (Model.xcdatamodel), without changing the version of the model and installed it on my iPhone for testing -> Crash with message "Cannot migrate store in-place: constraint violation during attempted migration".

  2. I created a new version of the model (Model 2.xcdatamodel) and made the changes there. I then created a .xcmappingmodel to manage the migration. No crash & it worked, however...

  3. All entries in my app are now duplicated, which of course was not as intended.

What I changed in the model:

My original (source) model had two entities A and B. There is a many-to-many mapping between A and B. I did the following changes.

  • Add two new entities C and D, with one data field ("name")
  • Create a 1-to-many mapping between each of the two new entities C, D and one of my existing ones (A)

I did just create the .xcmappingmodel-file and not change anything in it. For the existing entities A and B it has the entries to take over the previous data, like this:

destination attribute: name
value expression: $source.name

For the existing mapping A-B (entity B is called "Tag") it has: FUNCTION($manager, "destinationInstancesForEntityMappingNamed:sourceInstances:" , "TagToTag", $source.tags) And similar for the inverse relationship.

How I build my CoreData stack

I followed the documentation from Apple. My code looks like this (I made a CoreDataManager-class):

[...]
lazy var persistentContainer: NSPersistentContainer = {
    let container: NSPersistentContainer
    container = NSPersistentCloudKitContainer(name: containerName)
    let storeDescription = container.persistentStoreDescriptions.first
    storeDescription?.type = NSSQLiteStoreType

    container.loadPersistentStores { (_, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error when loading CoreData persistent stores: \(error), \(error.userInfo)")
        }
    }
    return container
}()

lazy var mainContext: NSManagedObjectContext = {
    let context = self.persistentContainer.viewContext
    context.automaticallyMergesChangesFromParent = true

    return context
}()
[...]

I don't really know what I did wrong or how I can fix this. Would appreciate if anybody can point me in the right direction.

0 Answers0