Search code examples
iosswiftcore-dataicloudcloudkit

CloudKit fails to sync with CoreData with Constraints


I have a data model with a constraint to ensure an attribute is unique.

When I reinstall the app (with data being available in the cloud), the sync fails with the following error:

2020-07-16 10:33:13.401904+0200 Structured[40519:1639423] [error] error: CoreData+CloudKit: -[PFCloudKitImporterZoneChangedWorkItem applyAccumulatedChanges:error:]_block_invoke_2(440): Failed to save applied changes from import: Error Domain=NSCocoaErrorDomain Code=133021 "(null)" UserInfo={NSExceptionOmitCallstacks=true, conflictList=(
    "NSConstraintConflict (0x600000ab0600) for constraint (\n    day,\n    month,\n    year\n): database: 0xba46bc9a935a60ef <x-coredata://8AB04C93-B9EB-413F-BD0C-9EF854D89D20/Day/p1>, conflictedObjects: (\n    \"0xba46bc9a934e60ef <x-coredata://8AB04C93-B9EB-413F-BD0C-9EF854D89D20/Day/p4>\"\n)"
)}

This error reappears a couple of times and the remote data is never synced and merged with the locally available data.

I'm initalizing the persistance container in the usual way:

    lazy var persistentContainer: NSPersistentCloudKitContainer = {
        let container = NSPersistentCloudKitContainer(name: "Today")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        container.viewContext.automaticallyMergesChangesFromParent = true
        container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        return container
    }()

I found a similar issue which did not get answered.


Solution

  • You can't use unique constraints with NSPersistentCloudKitContainer, read here

    If you have conflicts that is developer error, and if you have duplicate records you can apply some form of deduplication with your own custom UUID field.