CloudKit 从推送通知中获取最新更改

问题描述 投票:0回答:1

我有一个可在多个平台(macOS、iOS、iPadOS 等)上使用的应用程序,我的目标是在 CloudKit DB 更改时更新每个平台上的小部件,而无需打开该应用程序。例如,现在,如果您在 iOS 应用程序中更改了某些内容,则需要打开 macOS 应用程序,等待 iCloud 同步,然后 macOS 小部件才会反映新数据。

我使用指南创建了订阅。它似乎有效,当我的 AppDelegate 中的数据发生更改时,我会收到推送通知。

    func application(
        _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
    ) {
        if CKNotification(fromRemoteNotificationDictionary: userInfo) != nil {

            ...
            let entries = container.viewContext.fetch(Entry.fetchRequest())
            var result = ... // generate widget state from entries
            ...
            UserDefaults.setValueForGroup(result, forKey: "widget_state")

            WidgetCenter.shared.reloadAllTimelines()
        } else {
            completionHandler(.noData)
        }
    }

问题是,当我从

viewContext
获取数据时,我得到的是旧数据。如何获取新数据?

根据我的发现,我可以使用

CKFetchDatabaseChangesOperation
并以某种方式从远程数据库获取并应用所有更改,但它有一个庞大的实现,看起来像是重新发明轮子。

如果我启动应用程序,所有同步都会自动发生,如何在收到推送通知后强制执行相同的行为?还是我错过了什么?

swift core-data cloudkit
1个回答
0
投票

目前尚不清楚您的记录区域订阅是如何配置的,但为了让您的应用程序能够在后台接收推送通知并更新数据,您需要将

shouldSendContentAvailable
设置为
true

具体操作方法如下:

    let subscription = CKRecordZoneSubscription(zoneID: yourRecordZoneId, 
                                                subscriptionID: yourSubscriptionId)
    let notificationInfo = CKSubscription.NotificationInfo()
    notificationInfo.shouldSendContentAvailable = true
    subscription.notificationInfo = notificationInfo

    try await database.modifySubscriptions(saving: [subscription], deleting: [])

在上面的示例中,我使用 Swift 并发来更新订阅,但您也可以使用

CKModifySubscriptionsOperation
操作或
CKDatabase.save(_:completionHandler:)
函数

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.