当CloudKit中的核心数据发生更改时,如何调用WidgetCenter.shared.reloadAllTimelines?

问题描述

我有一个使用CoreData和CloudKit的应用程序。更改在设备之间同步。主要目标具有已选中Remote notifications的“后台模式”功能,已在“服务”设置为CloudKit的情况下检查了iCloud功能,并在“已检查的容器”中纠正了容器。

我如何在代码中对记录的更改,删除添加做出反应?当CloudKit中的核心数据更改以更新iOS 14主屏幕小部件时,我需要致电WidgetCenter.shared.reloadAllTimelines()

我的目标是开始工作:我在icloud.developer.apple.com或其他设备上更改/添加/删除记录,并调用WidgetCenter.shared.reloadAllTimelines()以在小部件中显示正确的数据。应用可能在后台或前景。

来自AppDelegate.swift

func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Register for Remote Notifications
    application.registerForRemoteNotifications()
    
    return true
}

另外,在输出日志中也注意到了消息:

CoreData:调试:CoreData + CloudKit:-[[NSCloudKitMirroringDelegate remoteStoreDidChange:] _ block_invoke(2138):-由于出口商已掌握此事务,因此忽略远程更改通知:64/64-(URL:file:///var/mobile/Containers/Data/Application/F83C68DA-7C36-42CC-926D-7C721C679579/Library/Application%20Support/AppTitle.sqlite)

解决方法

如果您要订阅Core Data远程通知,可以使用onReceive

struct WidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        Text(entry.date,style: .time)
            .onReceive(NotificationCenter.default.publisher(for: .NSPersistentStoreRemoteChange)) { _ in
                // make sure you don't call this too often
                WidgetCenter.shared.reloadAllTimelines()
            }
    }
}

只需确保您不经常拨打reloadAllTimelines()-小部件可用的更新数量有限。