Core Data: Merging relevant changes between extensions and iCloud devices

I am working on an interactive widget and merging changes provided by a user over it with the app. I store my data, using Core Data. However, I noticed an issue with sync between other user's devices after that person made a change over the widget (in my case, it is completing a task). Here is my schema:

Main app: it looks for relevant transactions (https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes). When it found that one, the app merges changes:

if transaction.author == "widget" {
    if let userInfo = transaction.objectIDNotification().userInfo {
        NSManagedObjectContext.mergeChanges(fromRemoteContextSave: userInfo, into: [taskContext])
    }
}

Widget: If the user clicks on the checkbox in order to complete a task, using an AppIntent class, app creates an identical NSPersistentCloudKitContainer and completes the task. However, in that case, the NSPersistentCloudKitContainer of the widget does not look for changes.

That works correctly. However, only in a local environment. Here's why:

  1. If I complete a task (using a widget) and launch the app on the same device, the change will be synced correctly.
  2. If I complete a task (using a widget) (on device A) and launch the app on another device (on device B), the change will not be applied (on device B), until I open the app on the device that I made the change on (on device A).
  3. If I open the app on device B after I opened it on device A (and the changed has been applied), on device A I get a remote notification with the author value = 'NSCloudKitMirroringDelegate.import', not 'widget'.

The point of my issue is that the remote notifications about changes made, using widgets, does not arrive to other devices like notifications initialised by the main app. Thank you in advance!

Replies

To avoid complications when dealing with CloudKit, here is the strategy I am using:

  1. In the main app, I use a CoreDataStack with CloudKit enabled. The StoreDescription.cloudKitContainerOptions is not nil.
  2. In the widget extension, I use a CoreDataStack with CloudKit disabled. The StoreDescription.cloudKitContainerOptions is nil.

As a result, synchronization across multiple devices only occurs when the user launches the main app. If the user doesn't launch the main app, synchronization will not happen.