当 CloudKit 中的核心数据发生变化时,如何调用 WidgetCenter.shared.reloadAllTimelines()?

Igo*_* R. 3 core-data swift cloudkit widgetkit swiftui

我有一个使用 Core Data 和 CloudKit 的应用程序。更改在设备之间同步。主要目标有后台模式功能,检查Remote notificationsiCloud 功能,服务设置为 CloudKit,并检查容器中的正确容器。

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

我的目标是让这个工作:我在 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
}
Run Code Online (Sandbox Code Playgroud)

此外,在输出日志中注意到消息:

CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate remoteStoreDidChange:]_block_invoke(2138): <NSCloudKitMirroringDelegate: 0x281818d00> - 忽略远程更改通知,因为导出器已经赶上了这个事务:64 / 64 - <NSCloudKitMirroringDelegate: 0x281818d00>网址:file:///var/mobile/Containers/Data/Application/F83C68DA-7C36-42CC-926D-7C721C679579/Library/Application%20Support/AppTitle.sqlite)

paw*_*222 5

如果您想订阅 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()
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

只要确保您不要reloadAllTimelines()太频繁地调用- 您的小部件可用的更新数量可能有限。

  • 您真的确定这会按预期工作吗?根据我的理解,一旦小部件完成从“getTimeline”返回时间线,小部件扩展就会终止。因此,该侦听器只能在扩展生命周期内的几秒钟内进行侦听。根据我在文档中读到的内容,这种监听只能通过应用程序完成:https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date。看到这个被投票了,有没有人真正设法让它可靠地工作? (2认同)