CoreData: Request was cancelled because the store was removed from the coordinator

I am working with CoreData and WidgetKit. I would like to implement a NSPersistentCloudKitContainer into an interactive widget. However, when the user makes a change over the widget, the container does not sync the data until the user launches the app. I noticed an error:

error: CoreData+CloudKit: -NSCloudKitMirroringDelegate resetAfterError:andKeepContainer:: <NSCloudKitMirroringDelegate: 0x12f36e8e0> – resetting internal state after error: Error Domain=NSCocoaErrorDomain Code=134407 “Request ‘XYZ’ was cancelled because the store was removed from the coordinator.” UserInfo={NSLocalizedFailureReason=Request ‘XYZ’ was cancelled because the store was removed from the coordinator.}

I have found a potential solution: Migrating Data to App Groups Disables iCloud Syncing. However, it still does not work.

Here is the code of configuration the NSPersistentCloudKitContainer:

    let container = NSPersistentCloudKitContainer(name: "X")
    
    guard let privateStoreDescription = container.persistentStoreDescriptions.first else {
        fatalError("#\(#function): Failed to retrieve a persistent store description.")
    }
    
    let storesURL = //...
    privateStoreDescription.url = storesURL.appendingPathComponent("private.sqlite")
    privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
    privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)

    let sharedStoreURL = storesURL.appendingPathComponent("shared.sqlite")
    guard let sharedStoreDescription = privateStoreDescription.copy() as? NSPersistentStoreDescription else {
        fatalError("#\(#function): Copying the private store description returned an unexpected value.")
    }
    sharedStoreDescription.url = sharedStoreURL
            
    let containerIdentifier = privateStoreDescription.cloudKitContainerOptions!.containerIdentifier
    let sharedStoreOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
    sharedStoreOptions.databaseScope = .shared
    sharedStoreDescription.cloudKitContainerOptions = sharedStoreOptions

    container.persistentStoreDescriptions.append(sharedStoreDescription)
    container.loadPersistentStores(completionHandler: { (loadedStoreDescription, error) in
        if let loadError = error as NSError? {
            fatalError("\(#function): Failed to load persistent stores:\(loadError)")
        } else if let cloudKitContainerOptions = loadedStoreDescription.cloudKitContainerOptions {
            if .private == cloudKitContainerOptions.databaseScope {
                self._privatePersistentStore = container.persistentStoreCoordinator.persistentStore(for: loadedStoreDescription.url!)
            } else if .shared == cloudKitContainerOptions.databaseScope {
                self._sharedPersistentStore = container.persistentStoreCoordinator.persistentStore(for: loadedStoreDescription.url!)
            }
        }
                                
    })

    container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    container.viewContext.transactionAuthor = CoreDataStack.appAuthor
    container.viewContext.automaticallyMergesChangesFromParent = true
   
    do {
        try container.viewContext.setQueryGenerationFrom(NSQueryGenerationToken.current)
    } catch {
        fatalError("\(#function): Failed to pin viewContext to the current generation:\(error)")
    }
    
    return container

Localisation of the stores is based on the App Group.
Thanks in advance!

Leave a Comment