swift - CoreData 和 CloudKit Sync 有效,但 NSPersistentStoreRemoteChange 通知永远不会触发

标签 swift core-data push-notification notifications cloudkit

我已经更新了一个现有的 CoreData 应用程序以使用 CloudKit,以便它可以在多个设备之间保持数据同步(对于同一个 iCloud 帐户)。

有效!数据同步很好。

但主 UIViewController 的 View 不反射(reflect)新数据。要查看更改,我必须切换到不同的 View ,然后切换回主视图,该 View 在其 viewWillAppear() 函数中调用了 refreshData()。然后它从数据存储中重新读取并显示所有数据(包括在其他设备上更新的任何数据)。

UIViewController 应该根据下面的 viewDidLoad() 观察 NSPersistentStoreRemoteChange 通知:

    override func viewDidLoad() {
        super.viewDidLoad()
    //  NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: AppDelegate.appDelegate().persistentContainer.persistentStoreCoordinator)
        NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: nil)
    }

但是处理函数永远不会被调用:

    @objc func handleRemoteChange(notification: Notification) {
        print("Handling remote change to data in Collection Controller")
        refreshData()
    }

那个 print 语句从不打印任何东西,那里设置的断点也从不触发。

我已将托管对象上下文配置为在创建 NSPersistentCloutKitContainer 后立即根据需要合并来自父对象的更改:

    container.viewContext.automaticallyMergesChangesFromParent = true

该应用程序具有我在网上(和 Stack Overflow)搜索线索后了解到的所有相关 iCloud 功能和权利,包括:

  • “远程通知”(后台模式)
  • “CloudKit”(iCloud)
  • 已创建并选择了一个容器,其标识符为 格式:iCloud.reverse.domain.app

容器的 persistentStoreDescription 将 NSPersistentStoreRemoteChangeNotificationPostOptionKey 选项设置为 true:

        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                print("FAILED to load persistent store:\(storeDescription)\nERROR:\n\(error)\n\(error.userInfo)")
            }
        })

        container.viewContext.automaticallyMergesChangesFromParent = true
        for description in container.persistentStoreDescriptions {
            description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
        }

很明显,数据正在同步。只是通知没有按预期工作。因此最终用户不会自动看到新的/同步的数据。

我怎样才能让它工作?

最佳答案

我有同样的问题,通过在调用 loadPersistentStores(completionHandler:) 之前配置自定义持久存储描述解决了

container = NSPersistentCloudKitContainer(name: "RubikClub")
// turn on persistent history tracking
let description = container.persistentStoreDescriptions.first
description?.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description?.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
NotificationCenter.default.addObserver(self, selector: #selector(type(of: self).storeRemoteChange(_:)), name: .NSPersistentStoreRemoteChange, object: container.persistentStoreCoordinator)

container.loadPersistentStores { (_, error) in
  if let error = error {
    fatalError("init core data error: \(error.localizedDescription)")
  }
}
container.viewContext.automaticallyMergesChangesFromParent = true

关于swift - CoreData 和 CloudKit Sync 有效,但 NSPersistentStoreRemoteChange 通知永远不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61790440/

相关文章:

ios - 获取用于推送通知的生产 iOS 设备 token

ios - iPhone 和 iPad 项目分离

swift - swift 结构二叉树

ios - 将 JSON 导入核心数据

android - 关于如何在 android 的安装类中使用 Rest API(服务)传递 ParseObject(对象)?

ios - iOS 13通知服务扩展程序似乎忽略了应用程序特定的首选语言。是 bug 吗?

ios - 为什么使 UIApplicationDelegate 中的 window 属性为可选而不是隐式解包可选?

ios - 在应用程序终止后运行代码......可能吗? (Xcode 8, swift 3)

swift - 根据段显示正确的文本颜色?

ios - CoreData 何时实际写入 sqlite 文件?