Search code examples
iosswiftcore-datacloudkitwidgetkit

How to update WidgetKit timeline entries when Core Data data in CloudKit changes?


I have an app that uses Core Data with CloudKit. Changes are synced between devices.

Main target has Background Modes capability with checked "Remote notifications". Main target and widget target both have the same App Group, and both have iCloud capability with Services set to CloudKit and same container in Containers checked.

For accessing Core Data data from widget I use CoreDataStack, as shown in this answer. In WidgetKit file I have a function that performs fetch request and returns Int — a number of rows from that request. Later I show that number in widget view.

But, if Core Data data in CloudKit changes, for example — on another device user added or deleted records, that Int may be incorrect.

How to request update WidgetKit timeline entries, when such changes happens? (If data changed on another device or on a current device.) Thanks.


Solution

  • A possible solution is to observe the NSPersistentStoreRemoteChange notification.

    In your Core Data Stack:

    let container = NSPersistentContainer(name: "MyStuff")
    let description = container.persistentStoreDescriptions.first
    description?.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
    

    And then you can detect the notifications like described here:


    There is one drawback though: when the remote changes are detected this notification is fired more than once (usually in short series). To avoid refreshing too often, you may want to use a Timer to delay refreshing.