我知道这个答案来晚了,并且 实际上并不具体到 OP 所指的 WWDC 19 SynchronizingALocalStoreToTheCloud Apple's sample project,但我有 同步问题(不是在启动时,当它同步正常时,但仅在应用程序处于活动状态但空闲期间,这似乎是原始问题的案例 3) 在使用 Core Data + CloudKit 和 NSPersistentCloudKitContainer 的项目中,我相信我遇到了同样的问题 - 现在显然我已解决 - 可能会影响将来阅读此问题的其他用户。
我的应用从一开始就是使用 Xcode 的 11 Master-Detail 模板和 Core Data + CloudKit 构建的,所以最初我只需要做很少的同步工作:
- 在我的目标的签名和功能中启用远程通知后台模式;
- 为 CloudKit 添加 iCloud 功能;
- 选择容器iCloud.com.domain.AppName
- 添加
viewContext.automaticallyMergesChangesFromParent = true
基本上,我关注了Getting Started With NSPersistentCloudKitContainer by Andrew Bancroft,这足以让 MVP在设备(Catalina、iOS 13、iPadOS 13)之间同步,不仅是在启动时,而且在应用程序运行和激活时也是如此(感谢上面的步骤 4)和另一个设备编辑/添加/删除了一个对象。
作为 Xcode 模板,它没有 WWDC 2019 示例项目的额外自定义/高级行为,但它实际上完成了目标好吧,我很满意,所以我继续开发这个应用程序的其他部分,不再考虑同步。
几天前,我注意到 iOS/iPadOS 应用程序现在只在启动时同步,而不是在应用程序在屏幕上处于活动和空闲状态时同步;在 macOS 上,行为略有不同,因为在重新激活应用程序时,一个简单的命令选项卡触发了同步,但同样,如果 Mac 应用程序位于最前面,则不会同步来自其他设备的更改。
我最初指责我在此期间所做的一些修改:
- 为了在共享扩展中访问 sqlite,我通过继承 NSPersistentCloudKitContainer 将容器移动到应用组中;
- 我更改了应用名称的大小写,由于无法删除 CloudKit 数据库,我创建了一个名为 iCloud.com.domain.AppnameApp 的新容器 (CloudKit 是显然,不区分大小写,是的,我真的应该开始不太关心这些事情了)。
虽然我很确定在每次这些更改之后我看到同步工作以及之前的工作,但同步(显然)突然中断至少几个小时让我确信这些修改中的任何一个都不是默认的path 导致在应用程序处于活动状态时停止接收通知,然后合并只会在启动时发生,正如我所看到的,因为正在运行的应用程序没有意识到更改。
我应该提一下,因为这可以帮助在我的情况下的其他人,我确信通知是在 Core Data 上下文保存时触发的,因为 CloudKit Dashboard 显示正在发送的通知:
所以,我尝试了几次清除派生数据(永远不知道),删除所有设备上的应用程序并重置 CloudKit 仪表板中的开发环境(我在开发过程中已经定期这样做了),但我仍然有没有收到通知的问题。
最后,我意识到重置 CloudKit 环境并删除应用程序确实很有用(我实际上重新启动了所有东西只是为了安全 ;)但是我还需要删除应用程序数据来自 iCloud (在从其他设备中删除后,在最后一个仍安装了该应用程序的 iOS 设备上的 iCloud 设置屏幕上)如果我真的想要一个干净的状态;否则,我有些混乱的数据库会同步回新安装的应用程序。
确实,具有全新开发环境、新安装的应用程序和重新启动的设备的真正干净的状态在应用程序位于最前面时也会恢复从设备检测到的通知。
所以,如果你觉得你的设置是正确的并且已经阅读了足够多的时间viewContext.automaticallyMergesChangesFromParent = true是你唯一需要的东西,但仍然看不到来自其他设备的变化,不要排除某些东西可能已经超出你的控制范围 (不要误会我的意思:我 100% 确定这一定是我所做的!) 并尝试重新开始......这可能看起来晦涩难懂,但 我们为应用选择的同步方法有什么问题?