问题标签 [nspersistentcloudkitcontainer]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
113 浏览

ios - NSPersistentCloudKitContainer 错误处理

有时NSPersistentCloudKitContainer会在控制台报错,如下所示:

在我的代码中,我在加载持久存储时有错误处理,但是这个错误不会触发它,因为这个错误是在存储加载之后出现的。

我在哪里处理这些错误?如何在代码中看到这些错误?

0 投票
0 回答
195 浏览

ios - 将 NSPersistentCloudKitContainer 迁移到 AppGroup 会导致 CloudKit 重新同步并创建重复对象

我在应用程序中有一个使用 NSPersistentCloudKitContainer 的 CoreData 存储。当我将它迁移到 AppGroup 时,它认为它之前没有执行过同步,所以重新同步CKRecords到数据库,这意味着所有对象都有重复的记录。无论如何将迁移的存储标记为与最新的更改令牌同步,这样它就不会执行这个新的拉取?

0 投票
2 回答
330 浏览

ios - 需要 iCloud 时如何处理首次启动体验?

CloudKit用来存储公开可用的数据,并将新数据NSPersistentCloudKitContainer作为我的核心数据堆栈的一部分来存储/同步私有数据。

当用户打开我的应用程序时,他们处于 4 种状态中的 1 种状态:

  1. 他们是可以访问 iCloud 的新用户
  2. 他们是可以访问 iCloud 的老用户
  3. 他们是新用户,但由于某种原因无法访问 iCloud
  4. 他们是老用户,但由于某种原因无法访问 iCloud

状态 1 和 2 代表我的快乐之路。如果他们是新用户,我想在显示初始视图之前用一些数据播种用户的私人商店。如果他们是返回用户,我想从 Core Data 获取数据以传递给初始视图。

确定新老用户: 我的计划是使用NSUbiquitousKeyValueStore. 我对此的担忧是处理以下情况: 下载应用程序->被记录为之前启动过应用程序->删除并在新设备上重新安装/安装应用程序 我认为NSUbiquitousKeyValueStore需要一些时间来接收更新,所以我需要等到它完成同步后再移动到初始视图。那么问题来了,如果他们无法访问 iCloud,会发生什么?NSUbiquitousKeyValueStore如果无法接收更新,如何告诉我他们是否是回访用户?

确定 iCloud 访问权限: 根据我所做的研究,我可以检查iCloudFileManager.default.ubiquityIdentityToken是否nil可用,但这不会告诉我原因。我将不得不使用CKContainer.default().accountStatus来了解为什么 iCloud 不可用。问题是这是一个异步调用,我的应用程序会在了解他们的帐户状态之前继续前进。

我真的在这个问题上摸不着头脑。优雅地确保处理所有这些状态的最佳方法是什么?

0 投票
0 回答
252 浏览

swift - NSPersistentCloudKitContainer 将 NSManagedObject 子类恢复为历史值

NSPersistentCloudKitContainer我有一个用于与 iCloud 同步数据的应用程序。用户报告偶尔会丢失数据,之后我开始调试我的实现。

我的应用程序实现的一部分是显示一个显示信息并有一个确认按钮的弹出窗口。当用户单击此按钮时,自定义子类的一个或多个实例NSManagedObject被修改。

同时,NSPersistentCloudKitContainer当应用退出并变为活动状态时,会触发一个镜像进程。当用户单击上述确认按钮时会发生这种情况。它通过执行NSCloudKitMirroringExportRequestandNSCloudKitMirroringImportRequest请求来做到这一点。

换句话说,在我的应用程序中,数据同时被修改(通过代码显式)和镜像(通过 CloudKit 隐式),这就是问题所在。

本质上是这样的:

  1. NSTimeInterval子类实例的属性 ( )NSManagedObject递增(例如 0 + 1 = 1)。
  2. NSPersistentCloudKitContainer当应用程序激活或退出时隐式开始镜像数据。
  3. 在此过程中但在完成之前,该属性会再次递增(例如 1 + 1 = 2)。
  4. 在内部,镜像过程完成。

在这个阶段,我希望属性的值与最新的(本地)更改相匹配(因此在我的示例 2 中)。但相反,它匹配初始增量(因此在我的示例 1 中),覆盖我的最新(本地)更改导致数据丢失。显然,NSCloudKitMirroringImportRequest恢复到镜像进程启动时的状态,也可以在日志中看到:

在这个阶段,我不确定这是否是NSPersistentCloudKitContainer我的应用程序中的错误,但它肯定会导致数据不可靠。目前我有这些问题:

  1. 为什么NSPersistentCloudKitContainer(特别是由于NSCloudKitMirroringImportRequest)导入“更新的”记录,而这些记录仅在本地更改?换句话说:我已经有了最新版本的记录。由于那些“更新”的记录具有过时的值,这会覆盖我的新更改,从而导致数据丢失。跳过这些更新将解决我的问题。有没有办法控制这种行为?
  2. 似乎(显式)更改数据和(隐式)同时镜像它们会导致问题。在我的情况下,由于NSPersistentCloudKitContainer在应用程序激活或退出时安排了镜像过程,这会自动发生。有没有办法控制这种行为?例如,我可以在应用程序激活或退出时禁用镜像过程吗?我注意到NSCloudKitMirroringDelegateOptions默认为automaticallyScheduleImportAndExportOperations:YES. 我可以改变这个吗?在不太可能发生数据突变的时刻,我是否也可以自己显式地触发镜像过程?

最后,可以在没有连接到 Internet 时(因此,CloudKit 无法镜像数据),事情按预期工作。

0 投票
0 回答
223 浏览

macos - NSPersistentCloudKitContainer 不在 macOS 上同步数据

我正在使用NSPersistentCloudKitContainer在 iOS 和 macOS 应用程序之间共享数据。

我已经根据官方教程设置了项目。当我从 macOS 应用程序进行更改时,最新数据将自动显示在我的 iOS 应用程序上。但另一方面,当我在 iOS 上进行更改时,macOS 应用程序将无法获取最新版本的数据。

我已经在 Cloud Dashboard 上验证了在 iOS 上所做的更改已上传到 CloudKit 服务器。只是 macOS 应用程序和云进程不会创建任务来拉取这些更改(从 console.app 观察到)。如果我退出 macOS 应用程序并重新启动它,将提取最新数据。

所以问题是 macOS usingNSPersistentCloudKitContainer不会在运行时获得同步数据。

一个可能的原因是官方教程已经提到设置后台远程通知。我已经为 iOS 应用程序做到了这一点。但是对于 macOS 应用程序,没有后台模式选项,所以我跳过了这一步。

有什么想法可以及时在 macOS 上获取同步数据吗?非常感谢!

0 投票
1 回答
1420 浏览

swift - 将数据迁移到应用程序组会禁用 iCloud 同步

我正在向我现有的应用程序添加今日扩展。我已经添加了一个 App Group 并使用这篇文章成功地将我的 Core Data 的数据迁移到了 App Group 的商店。我的应用同时使用 NSPersistentCloudKitContainer(当 iCloud 开启时)和 NSPersistentContainer(iCloud 关闭)。虽然两个容器中的数据都成功迁移,但在使用 NSPersistentCloudKitContainer 时,我不再能够在我的设备之间同步。在控制台中,我收到这两个错误:

CoreData: 错误: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(837): : 无法为商店设置 CloudKit 集成: (URL: file://path/name.sqlite)

错误域 = NSCocoaErrorDomain 代码 = 134060 “发生核心数据错误。” UserInfo={NSLocalizedFailureReason=镜像委托无法初始化,因为它的存储已从协调器中删除。}

第一条错误消息的路径是切换到 App Groups 之前 oldURL 的路径。所以我相信我只需要告诉 iCloud 不要尝试在该商店位置集成 CloudKit 并使用 App Group 的商店位置。

但我无法弄清楚如何做到这一点。任何人都可以帮忙吗?

核心数据代码:

0 投票
0 回答
185 浏览

swift - 使用 NSPersistentCloudKitContainer 的可选核心数据关系问题

我正在使用 NSPersistentCloudKitContainer,不确定这是我的问题还是 CloudKit 通用行为的原因。同步设置到目前为止工作正常。我现在正在添加一个新功能,导致一些问题:

我有一个实体项目,可以放在一个组中。CD 中的关系是一对一且可选的。在设备上工作正常:我可以设置和删除组,一切都保持不变。

但是当我删除组时,CloudKit 只是忽略了。它不抱怨,只是忽略它。无论删除是从项目、组还是双方发生。在下一次下载时,它又回到了一个组中。它只是 NSPersistentCloudKitContainer 中的一个错误吗?CloudKit 记录上的字段可以为零,对吗?

我在 CloudKit 仪表板中看到的内容: • Item 上的 Group 字段是 String 类型。• 从未分配给组的新项目记录没有组字段。• 一旦它得到一个组字段,我就无法摆脱它。清空值会导致崩溃。

当我在设备上获取 CloudKit 记录时,它甚至没有 group 字段。所以我不能手动重置它。它仅在 CloudKit 仪表板中显示 Group 字段。我猜容器在内部处理关系并且只在同步期间映射它。

有没有办法妥善处理这个问题?

0 投票
1 回答
124 浏览

ios - NSPersistentCloudKitContainer 被多个进程写入

我有一个使用 iCloud 和 Core Data 的应用程序NSPersistentCloudKitContainer。容器和相关代码在一个共享框架中,大多数东西都运行良好。除了应用程序本身,我还有一个共享扩展和一个意图扩展。

我遇到的问题是,如果其中一个扩展在应用程序处于活动状态时写入数据库。NSPersistentCloudKitContainer似乎在这两个过程中都做了一些魔术,当它发现魔术已经完成时,它无法更新某些数据。例如,我在两个托管对象之间存在一对一的关系(需要与 cloudkit 支持的模型相反)。关系的一侧变为有效,而另一侧为零。

我在控制台中收到错误消息说 CloudKit+CoreData 无法合并数据库和容器缓存之间的差异。我很确定这是一个疏忽,NSPersistentCloudKitContainer没有考虑到这个特定场景(共享框架、多个开放进程)。

有没有人幸运地使用NSPersistentCloudKitContainer和保存来自扩展的关系的数据?

0 投票
0 回答
73 浏览

core-data - 检测/接收 CloudKit CoreData 错误

在开发过程中,我已经切换到NSPersistentCloudKitContainer并开始了尝试测试尽可能多的场景以确保没有人丢失任何数据的可怕过程。

在一些测试中,我看到了这样的错误:

我能够解决这个问题,但它只会影响某些场景,如果这发生在真实用户身上,他们(和我)永远不会知道这个问题,他们的数据也不会同步到 CloudKit。

如果商店加载失败,你会得到一个错误,但如果它加载但不同步,你就不会。

所以我的问题是:有没有办法在代码中接收这些错误?

我一直在寻找通知和委托方法,但找不到任何东西。

0 投票
1 回答
227 浏览

ios - 如何使用 NSPersistentCloudKitContainer 预加载 Core Data SQLite 文件

我有一个 Core Data+CloudKit 配置,我需要为用户提供一些初始数据作为起点。它只有几个记录/对象,所以起初我尝试硬编码数据并在首次启动时写入核心数据。然后,用户可以添加和更改起点数据。

当我启用 CloudKit 同步时,我发现当启动同一帐户的第二台设备时,从 CloudKit 的角度来看,该设备新写入的默认数据是“更新的”。这意味着第二台设备上的默认数据将同步并覆盖用户自己在第一台设备上的数据。那很糟。

我相信正确的解决方案是在应用程序中提供预填充的核心数据文件 (.sqlite) 文件,以便在首次启动时,默认数据已经比用户在其他设备上创建的任何内容都旧。大多数教程和示例代码都非常古老,引用了 Swift 3、Xcode 7 等。我正在寻找一个在使用 NSPersistentCloudKitContainer 时有效的解决方案。

我在这个 SO question的答案中尝试了代码,将persistentContainer 的类型更改为 NSPersistentCloudKitContainer。这会编译并运行,但结果是我的应用程序在没有预加载数据的情况下启动,我不知道为什么。我在我的 Xcode 项目中包含了三个 .sqlite 文件,并将它们添加到“构建阶段”中的“复制捆绑资源”列表中。

这是我的代码: