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

2023-11-24

我的应用程序使用 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(使用前将#替换为@)

如何在 CoreData+CloudKit 应用程序中修剪历史记录? 的相关文章

  • 复杂对象上的自定义 NSSortDescriptor

    这是我的第一篇文章 如果我可能不尊重所有惯例 我很抱歉 尽管我会尽力而为 我以前总是在 SO 上找到解决我的问题的方法 但我完全陷入了一个相当复杂的可可问题 我正在尝试对 CoreData 对象列表进行复杂的排序 我有一个由 Book 对象
  • 如何从 iPhone 中删除 coredata

    您知道当您更改实体结构时如何重置 iPhone 模拟器上的核心数据存储吗 当我创建的核心数据存储的新版本与我上次在 iPhone 上运行的版本不同时 是否需要执行类似的过程 如果可以的话 请问如何 Thanks 只是为了方便起见 除非您编写
  • 核心数据:executeFetchRequest 与 PerformFetch

    我想要一份关于两者之间比较的完整列表 我所知道的事情 executeFetchRequest 消息已发送至 MOC 返回托管对象的数组 目标 从持久存储中获取对象到 MOC With table view 与表视图无关 频率 经常在循环中使
  • iOS 8 核心数据堆栈 - 致命错误:在解包可选值时发现 nil

    我对 iOS 开发比较陌生 决定实现自己的 Core Data 堆栈 替换 Apple 的默认堆栈 我必须对我的代码进行更改 显然 并且能够弄清楚它 但在这种情况下我不能 这是我的代码 import UIKit import CoreDat
  • 强制设置核心数据检查点?

    我编写了一个通过 Core Data 搅动大量数据的应用程序 用户在后台退出应用程序后 我会清理这些数据 由于 WAL 检查点似乎是导致 UI 暂停的主要原因 因此我还想强制使用 WAL 检查点 是的 我知道创建第二个核心数据堆栈 这也将完
  • UITableView 未更新

    我正在使用核心数据模型和 UITableViewController 表视图 我的模型似乎工作得很好 但是当我向模型添加实体时 我的表视图没有更新 我相信我的模型有效的原因是 当我添加一个实体时 在运行时视图中不会显示任何内容 但是如果我剪
  • 为什么我需要在核心数据项目中使用原始访问器方法?

    为什么我需要在核心数据项目中使用原始访问器方法 我正在阅读有关核心数据的内容并注意以下内容 默认情况下 Core Data 动态地 创建高效的公共和原始的 获取和设置访问器方法 建模属性 属性和 管理对象的关系 课程 例如 给定一个实体 属
  • iOS 的云存储选项

    我正在尝试创建一个后端 让许多用户可以在我正在创建的 iPhone 应用程序中相互通信 我尝试过使用 Core Data Google App Engine Google Cloud Storage 和 Amazon Web Service
  • 使用 CoreData 进行 Swift 包单元测试

    我有一堆快速文件 它们提供了 CoreData 之上的一些服务 我的单元测试运行良好 我决定使用 XCode 11 将所有这些移至 Swift 包中 单元测试不再运行 运行时错误为caught NSInternalInconsistency
  • 如何保证主机应用程序和扩展程序使用的共享应用程序容器中的核心数据存储中的唯一条目?

    为了有效地提出我的问题 让我们首先考虑一下我面临的具体场景 常规设置 一个主机 iOS 8 应用程序 与主机应用程序捆绑在一起的一个或多个 iOS 8 扩展 WatchKit Share 等 主机应用程序和所有扩展在共享应用程序组容器中共享
  • 使用简洁形式的 NSManagedObjectID URI?

    在我的应用程序中 我使用 Core Data 以及不使用 Core Data 的附加 sqlite 数据库 在这个附加数据库中 我有一些列存储对NSManagedObject实例通过每个实例的NSManagedObjectID 我得到一个实
  • 跳过痛苦的 Core Data 迁移并迁移到新的数据模型

    当我什至不关心旧数据时 我花费了大量时间将核心数据整理到新的迁移中 有没有一种方法可以删除所有现有数据并跳转到新的数据模型 而不是每次更改数据模型时都处理映射模型的麻烦 是的 只需删除商店文件并重新创建即可 我经常 至少在开发过程中 让我的
  • 如何让NSManagedObject不出错?

    我目前正在调试另一个开发人员编写的一个大项目 该项目使用CoreData我对此很陌生 我遇到了崩溃 这是由于某些NSManagedObject是一个错误 我对什么是错误不太了解 我想将对象转换为 非错误 看看它是否有帮助 阅读文档让我想到t
  • 如何判断“NSManagedObject”是否已被删除?

    我有一个NSManagedObject已被删除 并且包含该托管对象的上下文已被保存 我明白那个isDeleted回报YESif Core Data 将要求持久存储在下一次保存操作期间删除该对象 然而 由于保存已经发生 isDeleted回报
  • CoreData 和 SwiftUI:环境中的上下文未连接到持久存储协调器

    我正在尝试通过构建一个作业管理应用程序来自学核心数据 我的代码构建良好 应用程序运行正常 直到我尝试将新分配添加到列表中 我收到这个错误Thread 1 EXC BREAKPOINT code 1 subcode 0x1c25719e8 在
  • 保存时出现 iphone 核心数据未解决的错误

    尝试保存时 我从核心数据中收到一条奇怪的错误消息 但问题是错误不可重现 在执行不同任务时 它会在不同时间出现 错误消息 Unresolved error Domain NSCocoaErrorDomain Code 1560 UserInf
  • 可以使用两个独立的 SQLite 数据库吗?

    我有一个 sqlite 数据库 其中存储用户定义的信息和用户只读的信息 我觉得将来可能需要修改只读信息 并且我不想进行整个数据迁移 有没有一种方法可以使用单独的 sqlite 数据库来存储只读信息 该数据库可以轻松替换 如果是这样 您能否就
  • 在 insertMethod 应用程序中使用 Core Data 会崩溃并给出 NSInternalInconsistencyException 并显示错误消息 Context已经有一个协调器

    我正在 xcode 4 2 中的 insertMethod 在 MasterViewController m 类中 实现一个核心数据示例 我的应用程序崩溃了NSInternalInconsistencyException 和错误消息 Con
  • DatePicker 停止 CoreData 按预期工作

    我有一个应用程序 它保存 UIDatePicker 中的文本和日期 然后在您回到 UIDatePicker 中的该日期时显示该注释 效果很好 只有我发现将 UIDatePicker 日期设置为今天会停止 CoreData 工作 只有当我运行
  • 错误:更改核心数据模型后架构armv7的重复符号

    我有一个使用核心数据框架的应用程序 我工作得很好 我刚刚更改了数据模型 向一个实体添加一个属性 当我尝试构建它时 出现错误 duplicate symbol OBJC METACLASS AccountFolder in Users XXX

随机推荐