我的应用程序使用 CoreData 和 iCloud 作为后端。多个设备可以访问 iCloud 数据库,因此.public
.
本地 CoreData 存储使用 iCloud 同步NSPersistentCloudKitContainer
.
我根据以下方式使用历史记录跟踪苹果的建议.
在那里,苹果建议尽可能删除历史记录。他们说
因为持久历史跟踪事务占用了空间
磁盘,确定清理策略以在它们不存在时将其删除
更需要。在修剪历史之前,单个网守应该
确保您的应用程序及其客户端已消耗了他们的历史记录
需要。
最初这也被建议在WWDC 2017 演讲26:10 开始。
我的问题是:如何实现这个单一的看门人?
我认为这个想法是单个实例知道应用程序的每个用户上次同步其设备的时间。如果是这样,则可以删除该日期之前的交易历史记录。
但是,如果用户同步了本地数据,然后很长时间不再使用该应用程序怎么办?在这种情况下,在该用户再次同步本地数据之前,无法删除历史记录。因此历史数据可能会任意增长。在我看来,这是一个我不知道如何解决的核心问题。
上面引用的苹果文档建议:
与获取历史记录类似,您可以使用deleteHistory(before:)来
删除早于令牌、交易或日期的历史记录。为了
例如,您可以删除所有超过 7 天的交易。
但这并不能解决我心目中的问题。
除了这个普遍问题之外,我的想法是在公共 iCloud 数据库中拥有一个 iCloud 记录类型,直接为每个设备存储(即没有 CoreData)本地数据库更新的最后日期。由于所有设备都可以读取这些记录,因此很容易识别上次更新所有本地数据库的时间,并且我可以修剪该日期之前的历史记录。
这是处理问题的正确方法吗?
EDIT:
该问题最近已在这个帖子。作者通过苹果演示应用程序的测试证明,如果过早清除历史记录,确实存在问题。我的答案在那里表示建议延迟 7 天,错误可能极其罕见。
UPDATE:
In 这个帖子来自 WWDC22 核心数据实验室的 Apple Core Data 框架工程师回答了这个问题“我是否需要清除持久历史跟踪数据?“ 如下:
不,我们不推荐。 NSPersistentCloudKitContainer 使用
用于跟踪要同步内容的持久历史记录令牌。如果删除历史记录
云同步已重置,必须从头开始上传所有内容。它
会恢复,但这不是良好的客户体验。不应该
通常需要删除历史记录。例如,苹果照片
应用程序不会修剪其历史记录,因此除非您生成大量
大量的历史并不能做到这一点。
到目前为止,我认为我的问题部分是基于误解:
在 CoreData 中,持久存储由一个或多个持久存储协调器处理。
如果只有一个,则协调员对商店具有完全控制权,并且不需要历史跟踪。
如果有多个协调员,则一个协调员可以更改存储,而另一个协调员则不知道这些更改。
因此,商店的持久历史跟踪记录了商店中的所有交易。
然后,商店可以通过发送消息来通知商店的其他用户NSPersistentStoreRemoteChange
通知。
收到此通知后,可以获取并处理交易历史记录。
处理交易后,处理该交易的用户不再需要该交易。
在 CoreData + CloudKit 情况下,持久存储会镜像到 iCloud。
这意味着在最简单的情况下,应用程序有一个持久存储协调器,并且(对应用程序不可见)有一个执行镜像的持久存储协调器。
由于两个协调员都可以独立更改存储,因此需要历史跟踪。
如果应用程序更改了商店,我假设苹果的镜像软件会收到NSPersistentStoreRemoteChange
通知、处理交易并将其转发到 iCloud。通常,即如果有 iCloud 连接,这只需要几秒钟,因此交易历史只需要很短的时间。
如果 iCloud 更改已镜像到商店,则应用程序会收到NSPersistentStoreRemoteChange
通知,并必须处理交易。
处理后,应用程序和镜像软件都不再需要它们,并且可以对其进行修剪。
这意味着,如果应用程序的设备上只有一个持久存储用户,则确实可以在处理通知后短时间内完成修剪。
如果设备离线,例如飞行模式或关闭状态下,不会接收NSPersistentStoreRemoteChange
通知,并且不会删除交易历史记录。
因此,在处理持久性历史记录(例如 7 天后)后对其进行修剪确实是安全的。
如果一台设备上有多个商店用户,情况就会有所不同,例如一个额外的应用程序扩展。在这种情况下,必须确保在修剪历史记录之前,应用程序以外的其他目标也处理了交易。这确实可以由单个看门人来完成。如何做到这一点是例如描述于这个帖子.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)