core-datacloudkitnsmanagedobjectcontextnsmanagedobjectmodel

CoreData: Delete propagation prefetching failed using NSCKImportOperation


I am testing CoreData+CloudKit, i.e. I am using an NSPersistentCloudKitContainer that handles all communication with iCloud.
When I launch the app, CoreData automatically synchronizes with iCloud, i.e. (among others) inserted or updated records are imported to CoreData. No record is ever deleted.
My tests run on the simulator.

My 1st attempt was to use only the viewContext. To merge remote changes into this context, I set

viewContext.automaticallyMergesChangesFromParent = true

Additionally, I am using history tracking as suggested by Apple, with the exception that history processing also uses the viewContext, not a new background context.
This worked fine, except for the expected blocking of the UI by using the viewContext.

My 2nd attempt was thus to process the history by a background context (as suggested by Apple).
Now the following error is repeatedly logged (apparently forever):

CoreData: Delete propagation prefetching failed with exception: The fetch request's entity 0x6000017a2050 'NSCKImportOperation' appears to be from a different NSManagedObjectModel than this context's

This error is logged even after I deleted all iCloud records in the Dashboard, and deleted the app from the simulator.
I am using only a single NSManagedObjectModel with relations, but all relations have the delete rule „No action“.

To check the reason for this error, I set a runtime breakpoint, and the app stopped with the following stack trace:

enter image description here

I should mention that the error disappears, if I set

viewContext.automaticallyMergesChangesFromParent = false

but I need of course automatic merging for a correct operation.

My questions are:
Is this really an error? (The logs says „it appears…“).
What could be the reason for it, and how could it be avoided?

PS: There are many other posts related to CoreData prefetching, but I did not found one that relates to CoreData+CloudKit


Solution

  • I think the reason was a misconfiguration of my background context. It was set to retain all registered objects. As soon as I out commented the respective code, the error was gone:

    private (set) lazy var backgroundContext: NSManagedObjectContext! = {
        let context = persistentContainer.newBackgroundContext()
        context.name = "backgroundContext"
        
        // For possible merge policies see <https://developer.apple.com/documentation/coredata/nsmergepolicy/merge_policies>
        context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        
        /*
        CAUTION: DO NOT ENABLE THE FOLLOWING STATEMENT:
        context.retainsRegisteredObjects = true
        If enabled, the following error is reported indefinitely:
        ShopEasy[20204:2672392] [error] CoreData: Delete propagation prefetching failed with exception: 
        The fetch request's entity 0x600003764630 'NSCKImportOperation' appears to be from a different NSManagedObjectModel than this context's
        */
                
        // Pin the context to the current generation token and set it to keep itself up to date with local changes.
        context.automaticallyMergesChangesFromParent = true
        context.performAndWait {
            do {
                try context.setQueryGenerationFrom(.current)
            } catch {
                fatalError("###\(#function): Failed to pin viewContext to the current generation: \(error)")
            }
        }
        return context
    }()