ios 未收到共享Cloudkit数据库中更改的通知

fhg3lkii  于 2023-08-08  发布在  iOS
关注(0)|答案(1)|浏览(127)

c我在共享的Cloudkit数据库中有记录,但在应用运行时对这些记录进行更改(创建、更新或删除)时,我没有收到任何通知。如果我重新启动应用程序,我会看到更改。
据我所知,我需要使用CKDatabaseSubscription注册共享Cloudkit数据库中的更改。这是我目前所拥有的:

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {

        application.registerForRemoteNotifications()

        // Create database subscription to look for changes
        let subscription = CKDatabaseSubscription(subscriptionID: "todoChanges")

        // Does this need to be CD_Todo?
        subscription.recordType = "Todo"

        let notificationInfo = CKSubscription.NotificationInfo()
        notificationInfo.shouldSendContentAvailable = true

        subscription.notificationInfo = notificationInfo

        // Save to server
        let operation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: nil)

        operation.modifySubscriptionsCompletionBlock = { subscriptions, deleted, error in
            if let error = error {
                // Handle the error.
            } else {
                // ... cache/store in UserDefaults?
            }
        }

        operation.qualityOfService = .utility

        CKContainer.default().sharedCloudDatabase.add(operation)

        // Additional bits for SceneDelegate
        let config = UISceneConfiguration(
            name        : nil,
            sessionRole : connectingSceneSession.role
        )

        config.delegateClass = SceneDelegate.self

        return config
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("Change made in shared database")
    }
}

字符串
对于上面的代码,我不确定是否需要使用subscription.recordType的CoreData实体名称(“Todo”)或Cloudkit名称(“CD_Todo”)。话虽如此,但似乎都不起作用。
我还将订阅附加到共享数据库,我认为这是正确的,因为我希望在那里监视更改。我可以在iCloud Jmeter 板的“订阅”部分中看到订阅,这样我就可以验证它是否已保存。
除了上述我有“远程通知”选择的背景模式。我不认为我需要“背景提取”,无论如何启用它似乎没有什么区别。
在这一点上,我想做的就是让通知工作。最后,我希望应用程序在收到更改通知时获取最新的更改,但我似乎无法让第一部分工作,这最终会触发获取。
为了测试这一点,我一直在通过 Jmeter 板Web界面修改记录,但我没有看到“Change made in shared database”在Xcode中输出。据我所知,共享数据库是正确链接的,因为 Jmeter 板中所做的更改会在下次启动(或重新启动)时反映在我的应用程序中。

izkcnapc

izkcnapc1#

所以,我已经解决了我的问题,但我将在上下文中完整地解释这个问题。
我正在构建一个应用程序,该应用程序可以在区域范围内共享,以促进区域中所有记录之间的共享(而不是显式记录)。
之所以想得到通知,是因为我只得到了两个设备之间的单向同步。也就是说,设备A(iPhone)是所有者(私有数据库),设备B(模拟器)是参与者(共享数据库,具有对属于设备A的记录的读写权限)。在这个场景中,我可以从设备B创建/更新/删除Todo条目,它们会出现在设备A上,但反过来就不行了(除非我在设备B上重新启动应用程序)。这就是为什么我沿着通知的路径走下去--只是为了看看设备B是否至少在设备A做出更改时收到了一些东西。
然而,我随后想到颠倒共享的角色,以便设备A(iPhone)成为参与者,设备B(模拟器)成为所有者。在这个场景中,数据库被交换,设备A现在使用共享数据库,设备B使用私有数据库(由NSPersistentCloudkitContainer自动处理)。同样的事情发生了:更新从设备B到设备A(模拟器-> iPhone),而不是相反(iPhone ->模拟器)。然而,由于我交换了角色,因此数据库(我不确定共享数据库在幕后的行为是否与私有数据库不同),它指向了模拟器的一个问题(这开始是一个怀疑)。
无论如何,我通过在我的伴侣的设备上安装应用程序来确认这一点,并且立即在两个方向上共享工作。此外,它不需要任何订阅通知代码,如我上面的示例所示。我不知道是该哭还是该笑,因为我已经在这个问题上被卡住了,在房子里转了三天。
因此,如果有人发现这篇文章,并且遇到类似的问题,请尝试在两个物理设备之间进行设置(如果可以的话),因为它会出现,至少在我的情况下,模拟器在参与共享时不会收到更改通知。这是非常令人恼火的,因为苹果文档中没有提到这一点(据我所知),如果不参与共享,它响应通过Cloudkit Jmeter 板进行的更改。
就我的应用程序的其余部分而言,我并没有真正偏离苹果的例子,在设置NSPersistentCloudkitContainer与私人和共享数据库(例如。https://developer.apple.com/videos/play/wwdc2021/10015/?time=1264)但这就是我需要做的一切。我当然不需要创建过程来手动获取和更新本地数据,这似乎与他们的解释相反,但也许CloudKit近年来已经发展到承担更多必要的繁重工作。

相关问题