如何在CoreData + CloudKit应用中修剪历史记录?

问题描述

我的应用程序使用带有iCloud的CoreData作为后端。多个设备可以访问i .public数据库。
使用NSPersistentCloudKitContainer将本地CoreData存储与iCloud同步。
我根据Apple’s suggestions使用历史记录跟踪。
苹果公司建议在那里尽可能修剪历史。他们说

因为持久性历史记录跟踪事务占用了空间 磁盘,确定清理策略以将其删除。 需要更长的时间。在修剪历史记录之前,单个网守应 确保您的应用及其客户已经使用了他们的历史记录 需要。

最初,WWDC 2017 talk中也建议从26:10开始。

我的问题是:我该如何实现单个网守?

我认为这个想法是,单个实例知道应用程序的每个用户什么时候最后一次同步其设备。如果是这样,可以删除此日期之前的交易历史记录。
但是,如果用户同步了本地数据,然后长时间不再使用该应用程序怎么办?在这种情况下,除非该用户再次同步本地数据,否则无法删除历史记录。因此历史数据可以任意增大。在我看来,这是一个我不知道如何解决的中心问题。

上面引用的Apple文档建议:

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

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

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

这是解决问题的正确方法吗?

解决方法

到现在为止,我认为我的问题部分是基于误解:

在 CoreData 中,持久存储由一个或多个持久存储协调器处理。 如果只有一个,协调员对店铺有完全控制权,不需要进行历史追踪。

如果有多个协调员,一个协调员可以更改商店,而另一个则不知道这些更改。 因此,商店的持久历史跟踪记录了商店中的所有交易。 然后,商店可以通过发送 NSPersistentStoreRemoteChange 通知来通知商店的其他用户。 收到此通知后,可以获取和处理交易历史记录。 处理完交易后,处理它的用户不再需要它。

在 CoreData + CloudKit 的情况下,一个持久化存储被镜像到 iCloud。
这意味着在最简单的情况下,有一个应用程序的持久存储协调器,并且 - 应用不可见 - 一个执行镜像的持久存储协调器。
由于两个协调员可以独立更改商店,因此需要进行历史跟踪。

如果应用更改了商店,我假设 Apple 的镜像软件会收到 NSPersistentStoreRemoteChange 通知、处理交易并将它们转发到 iCloud。通常情况下,即如果有 iCloud 连接,这只需几秒钟,因此交易历史只需要很短的时间。
如果将 iCloud 更改镜像到商店,则应用会收到 NSPersistentStoreRemoteChange 通知,并且必须处理交易。
处理后,应用程序和镜像软件都不再需要它们,可以修剪它们。
这意味着如果应用程序的设备上只有一个持久存储的用户,那么在处理通知后的短时间内确实可以进行修剪。
如果设备离线,例如在飞行模式或关闭时,它不会收到 NSPersistentStoreRemoteChange 通知,也不会修剪交易历史记录。 因此,在处理完 7 天后修剪持久历史确实是安全的。

如果在一台设备上有多个商店用户,情况就不同了,例如一个额外的应用程序扩展。在这种情况下,必须确保在修剪历史记录之前,除应用程序之外的其他目标也处理了交易。这确实可以由单个看门人完成。如何做到这一点是例如this post 中描述。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...