问题标签 [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 投票
1 回答
214 浏览

swift - 查询Cloud Kit核心数据记录

我有一个应用程序,我正试图迁移到使用 CloudKit 来存储核心数据,以便它可以跨设备同步。

同步工作正常,我遇到的问题是应用程序向数据库添加了一些初始数据,这导致它在安装在另一台设备上时被复制。目前,如果已执行第一次运行,我正在使用用户默认值在本地存储布尔值,这显然只适用于每个设备

有什么方法可以查看云中是否已经存在数据并阻止添加初始数据。

如果对象已经存在但首次启动时本地商店中没有对象,Apple 的文档会建议它可能。 https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/reading_cloudkit_records_for_core_data

0 投票
3 回答
1023 浏览

ios - 应用程序卸载/重新安装后 CoreData + Cloudkit fetch() 不返回任何结果

我正在尝试配置 CoreData+CloudKitNSPersistentCloudKitContainer用于自动将数据同步到 CloudKit 或从 CloudKit 同步数据。

按照Apple 指南,设置实体、在 Xcode 中添加适当的功能、在我的 AppDelegate 中设置persistentContainer和设置都非常简单。saveContext

我正在通过 拨打电话fetch(),我可以毫无问题地保存和获取记录。我可以在 CloudKit 仪表板中看到它们。save()NSManagedObjectContext

但是,如果我从模拟器中卸载应用程序并重建/重新安装,我的fetchRequest(没有NSPredicate或排序,只是获取所有记录)总是返回一个空列表。我使用的是同一个 iCloud 帐户,并且我已经尝试过公共和私有数据库范围。如果我创建一条新记录,然后重试我的 fetch 请求,我可以检索新创建的记录,但不能检索任何旧记录。我 100% 确定这些记录仍在 CloudKit 数据库中,因为我可以在 CloudKit Dashboard Web 应用程序上看到它们。

我查看了Apple 的 CoreDataCloudKitDemo应用程序,它能够在卸载/重新安装后从 CloudKit 数据库中获取“发布”实体,所以我知道这是可能的。但是,它使用的是NSFetchedResultsController,它不适用于我的应用程序(我的是 SpriteKit 游戏)。

我尝试将我的 CoreData+Cloudkit 代码复制到一个全新的 Xcode 项目中,我可以在那里重现这个问题。这是我的代码供参考:

我错过了什么?为什么我只能获取在此应用安装期间创建的记录,而不能获取之前的记录?

更新:似乎如果我等待几秒钟并在第一次安装应用程序时重新尝试获取,我可以从 CloudKit 数据库中检索结果。首次启动时,我还可以在控制台中看到大量CoreData+CloudKit日志消息。这就是我的想法——即使在使用时NSPersistentCloudKitContainer,afetch()正在读取/写入本地 CoreData 存储,然后在后台运行一个单独的进程来镜像本地 CoreData 记录并将其与 CloudKit 记录合并。

因此,我相信我需要以某种方式等待/收到通知,本地 CoreData 和 CloudKit 记录的同步/合并已在首次启动时完成,然后再拨打我的fetch()电话,而不是fetch()在应用程序打开时立即拨打电话。有任何想法吗?

0 投票
1 回答
108 浏览

ios - 可以通过 NSPersistentCloudKitContainer 访问 creationDate 吗?

在 Cloudkit Dashboard 中,我可以看到记录的 Created 时间。

但是,在我的应用程序中,当我使用

我收到一个错误:

我怀疑我无法使用 NSPersistentCloudKitContainer 访问 creationDate?

0 投票
0 回答
283 浏览

core-data - NSPersistentCloudKitContainer 不在后台同步

我目前正在测试NSPersistentCloudKitContainer。我严格遵循新文档的指导方针。基本上一切都按预期工作。我在描述中使用选项NSPersistentStoreRemoteChangeNotificationPostOptionKey来接收来自远程数据存储的更新。但是只有当应用程序在前台时,远程数据库的更新才会被传递。但我想根据后端的数据更改更新我的小部件。

有谁知道如何解决这个问题?

到目前为止我做了什么:

  • 功能中的后台模式已启用
  • 推送通知已启用
  • 我打电话给 registerForRemoteNotifications
  • 在 PersistentStore 的描述中启用 HistoryTracking 和 RemoteChange 选项

在前台同步工作✅</p>

如果应用处于后台,则同步不起作用❌</p>

编辑:09.09.2020

似乎目前我们无能为力。Apple Developer Support 几天前回答了我的问题

感谢您联系 Apple 开发者技术支持 (DTS)。您描述的行为和由此产生的限制是设计使然。如果您认为 Apple 应该考虑另一种方法,我们鼓励您提交增强请求,并提供有关此设计决策如何影响您的信息,以及您希望看到哪些不同的做法。虽然没有承诺会改变行为,但这是确保负责决策的团队看到您对此事的想法的最佳方式。虽然技术支持事件 (TSI) 最初​​是从您的 Apple Developer Program 帐户中扣除此请求的,但我们已将替换事件分配回您的帐户。

0 投票
2 回答
136 浏览

ios - 通过 NSPersistentCloudKitContainer 更新 iCloud Scheme 到最新的 Core Data 版本

我一直在寻找将 CloudKit 方案迁移到我最新的本地核心数据模型的适当解决方案。即使推送新的更改,CloudKit 模型也不会更新。我尝试手动更新该方案,但它似乎有问题且非常耗时。有什么建议么?

0 投票
1 回答
205 浏览

core-data - CoreData+CloudKit 活动导入崩溃(iOS 14)

启动 CoreData+CloudKit (NSPersistentCloudKitContainer) 后很快就会通过抛出此异常而崩溃:

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“必须为活动标识符“com.apple.coredata.cloudkit.activity.import”注册一个处理程序。在提交之前以 CKException 类型的未捕获异常终止

我似乎找不到任何有关活动导入所需的处理程序的文档。我猜这是iOS 14的错误???

0 投票
1 回答
319 浏览

core-data - 如何在 CoreData+CloudKit 应用程序中修剪历史记录?

我的应用程序使用 CoreData 和 iCloud 作为后端。多个设备可以访问 iCloud 数据库.public
本地 CoreData 存储使用NSPersistentCloudKitContainer.
我根据Apple 的建议使用历史跟踪。
在那里,Apple 建议尽可能删减历史记录。他们说

因为持久性历史跟踪事务占用磁盘空间,所以确定一个清理策略以在不再需要它们时将其删除。在修剪历史之前,单一的看门人应该确保您的应用程序及其客户端已经消耗了他们需要的历史。

最初在 26:10 开始的WWDC 2017 演讲中也提出了这一建议。

我的问题是:我如何实现这个单一的看门人?

我假设这个想法是单个实例知道应用程序的每个用户上次同步他们的设备的时间。如果是这样,则可以修剪此日期之前的交易历史。
但是,如果用户同步了本地数据,然后长时间不再使用该应用程序怎么办?在这种情况下,在该用户再次同步本地数据之前,无法修剪历史记录。所以历史数据可以任意增长。在我看来,这是一个我不知道如何解决的核心问题。

上面引用的 Apple 文档建议:

与获取历史记录类似,您可以使用 deleteHistory(before:) 删除比令牌、交易或日期更早的历史记录。例如,您可以删除所有超过 7 天的交易。

但这并不能解决我心中的问题。

除了这个一般性问题,我的想法是在公共 iCloud 数据库中有一个 iCloud 记录类型,它直接为每个设备(即没有 CoreData)存储本地数据库更新的最后日期。由于所有设备都可以读取这些记录,因此很容易识别上次更新所有本地数据库的时间,并且我可以删除此日期之前的历史记录。

这是处理问题的正确方法吗?

0 投票
0 回答
213 浏览

ios - 使用 NSPersistentCloudKitContainer 时:如果用户退出 iCloud 怎么办?

从关于 CloudKit 的几个 Apple WWDC 谈话中,当使用 CloudKit 跨设备同步私人用户数据时,当用户注销 iCloud 时,应用程序应该清空设备缓存/本地副本(我使用 Core Data for on-device永久性)。然后,当该用户(或任何真正的用户)在同一设备上重新登录到他各自的 iCloud 帐户时,该设备应该从相应的 iCloud 帐户同步回数据。说得通!

我想知道当我使用 NSPersistentCloudKitContainer 时如何实现这一点(而不是自己编写所有 CloudKit 代码)。我查看了与 Apple WWDC 2019 session 202(“Using Core Data with CloudKit”)相关的示例代码,但此代码不是我想要的(示例只是不关注 iCloud 帐户部分,这就是他们不关注的原因懒得清空缓存,我认为):确实,如果我注销用户,NSPersistentCloudKitContainer 会停止同步,但是当我重新登录时它会再次同步。这实际上更像是期望的(实际上也是实际的,这很好) 当我的网络连接离线一段时间时示例应用程序的行为。

但是,如果用户从 iCloud 注销(我使用 CloudKit 框架来了解用户帐户注销和登录状态),我需要做的是:

  1. 从 NSPersistentCloudKitContainer “断开” sqlite 存储,然后
  2. 清空(甚至删除)数据库,然后,
  3. 当旧(或另一个)用户登录时,初始化一个新的 NSPersistentCloudKitContainer (它将重新创建一个空数据库,就像第一次使用该应用程序一样),因此可以继续与相应的云数据库进行通信。

我不能在“连接”到 NSPersistentCloudKitContainer 时清空数据库,因为它会记录所有删除,并且一旦(相同)用户再次登录,这些删除就会同步到云,我当然不想要.

这是怎么做的,也就是基本上遵循这三个步骤?

如果是,我该怎么做第 2 步?由于我必须使用某种 NSPersistentContainer 来与数据库对话,Apple 警告不要直接执行文件系统操作,而只能通过 Core Data。那么我是否需要初始化一个“标准”NSPersistentContainer(没有到云的通信管道),然后销毁数据库(例如,使用协调器实例方法destroyPersistentStore())?

还是有另一种方法可以实现相同的目标?

非常感谢您的帮助!!

0 投票
0 回答
111 浏览

core-data - 重命名关系时的核心数据和 CloudKit 集成问题(代码 134110)

我目前在 App Store 中有一个使用 Core Data 的应用程序:该应用程序允许人们记录他们的水上和航行活动(将其想象为水手的 Strava)。我已经 3 年没有更新该应用程序了,该应用程序似乎在最新的 iOS 版本上仍然可以正常运行,但我最近计划改进该应用程序。

我目前正在为此应用程序进行更新,并且需要更改数据模型和架构。我想要一个自动的轻量级迁移。我重命名了一些实体、属性和关系,但我确保将以前的 id 放在编辑器的 Renaming ID 字段中。我想利用这个机会在 CloudKit 上同步更新的模式。我按照 Apple Developer 文档中的说明设置同步。我还确保使用 initializeCloudKitSchema() 初始化架构。当我访问仪表板时,我看到了正确的架构。容器仅处于开发模式,未推送到生产中。

当我使用可用应用程序生成的 sqlite 文件启动应用程序时,迁移似乎运行良好,因为数据仍然存在并且正确。我可以在应用程序中正常导航,当我访问 CloudKit 仪表板时,数据已正确保存。

但有时,应用程序在启动时崩溃并出现以下错误:

相关实体被重命名,因为关系和关系是多对多的,双方都是可选的。即使我重置 CloudKit 开发容器,也会发生这种情况。我真的不清楚它何时出现(似乎是随机的,在我更新了一些数据之后或在我更新了核心数据模型之后)。知道为什么应用程序崩溃了吗?我希望尽可能为我的实体和关系保留新的命名。

  • SKPRCrewMemberMO 更名为 Sailor
  • SKPRTrackMO 重命名为 Activity
  • 船员 <<--->> 跟踪更名的水手 <<--->> 活动

以下是迁移问题起源实体的先前和更新数据模型的一些屏幕截图,以及一些关于我的核心数据堆栈初始化和控制台错误的代码。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

PS:该应用程序被数百人使用。这不是很多,但其中一些仍然有数十个记录的活动,我不想破坏任何东西并丢失或损坏数据。我可以启动一个新应用程序,但用户会丢失他们的进度,因为它只保存在本地共享容器中(使用应用程序组,因为我想与 Apple Watch 扩展共享核心数据)。而且我会失去用户群和 App Store 相关的东西。

0 投票
1 回答
106 浏览

ios - 从开发切换到生产时与 iCloud 帐户关联的数据

在将应用程序发送到 TestFlight 之前,我即将将我的 CloudKit 架构从开发切换到生产,但我对某些事情感到困惑。

在开发模式下进行测试时,我一直在 Core Data 中添加许多记录。有些是专门制作的,以便在未来的营销截图中看起来不错。借助 NSPersistentCloudKitContainer,它们可以在设备之间成功同步。这些记录与我的 iCloud 帐户和我的 Apple ID 相关联。

当我将架构切换到生产环境时,新的 beta 测试人员(以及后来的用户)将创建新记录,存储在他们自己的 iCloud 帐户中的私人数据库中,一切都很好。

但是我和我精心制作的数据会发生什么?

在模拟器和我的设备中,我仍将在生产中使用我在开发中使用的同一个 iCloud 帐户。这是否意味着我将保留现有数据?我认为部署到生产并没有复制记录......

所以,很明显,有些东西我不明白,在我采取下一步行动之前,我希望能得到一个解释来澄清问题。