如何使用当前的 NSPersistentStore 方法在本地和 iCloud 中创建可共享的 Core Data .sqlite 备份

How to create sharable Core Data .sqlite backups locally and in iCloud using current NSPersistentStore methods

我花了很长时间来找出创建 Core-Data 支持的 .sqlite 文件备份并存储该备份的正确方法,两者都本地 and/or 在 iCloud 中(无论用户喜欢什么) ),供下载、恢复或共享。让我先声明一下,我不是谈论将持久存储移动到 iCloud 以供应用程序用作其数据源。我只是问这个问题中创建备份文件的问题。

2014 年,Apple 将 Core Data SQLite 存储的默认日记模式更改为 WAL。

https://developer.apple.com/library/content/qa/qa1809/_index.html

有了这个变化,他们建议:

To safely back up and restore a Core Data SQLite store, you can do the following: Use the following method of NSPersistentStoreCoordinator class, rather than file system APIs, to back up and restore the Core Data store: - (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error

Note that this is the option we recommend.

在此之前,我一直在使用 NSFileManager 创建备份。有了这个建议,我相信在本地创建备份的正确方法是添加一个新的持久存储,然后将该持久存储迁移到所需的备份位置,使用 NSPersistentStoreCoordinator 方法 addPersistentStoreWithType:configuration:URL:options:errormigratePersistentStore:toURL:options:withType:error

我的问题有两个:

  1. 我以前会在导出之前将数据压缩到 NSData,并且 会将 NSData 直接写入文件。我的文件扩展名是 定制我的应用程序,用于通过电子邮件或其他方式共享压缩数据 iOS 分享方法。随着 migratePersistentStore:toURL:options:withType:error方法,我现在 最终得到一个 .sqlite 文件(及其相应的 WAL 文件等) 所需的位置,但我不知道如何共享此文件 现在。如果我压缩文件,我不会有丢失数据的危险吗? 努力通过使用来保存 migratePersistentStore:toURL:options:withType:error 在第一个 地方?我相信是这样,但我确实想让我的用户 share/save 他们的 备份通过电子邮件等,我现在不知道如何最好地解决这个问题。
  2. 我很难理解 migratePersistentStore:toURL:options:withType:error 可用于 将文件备份到 iCloud。就像上面的共享示例一样,我 看到我可以使用 addPersistentStoreWithType:configuration:URL:options:error,以及 migratePersistentStore:toURL:options:withType:error 获得 本地所需的 .sqlite 副本,但如果我随后尝试上传该本地文件 文件到 iCloud,我担心我会丢失我努力保存的数据 在中使用 migratePersistentStore:toURL:options:withType:error 第一名。我一直在尝试看看是否有办法让我 could/should 使用 migratePersistentStore:toURL:options:withType:error 移动 新创建的 persistentStore 直接到 iCloud,但我还没有 能够找到有关如何执行此操作或是否应该执行此操作的任何文档 完全完成了。是否需要使用特定的 url 来指示 persistentStore 的目的地是 iCloud?

如果能就这些问题的答案分享任何见解,我将不胜感激。

  1. ZIP 应该是 IMO 的安全方式,因为它具有用于数据完整性验证的 CRC 数据。

关于共享的 CoreData 存储版本,您必须小心。假设两个用户 运行 不同版本的应用程序并在彼此之间共享 CoreData 存储。 CoreData 不支持开箱即用的渐进式迁移。 https://www.objc.io/issues/4-core-data/core-data-migration/

也许共享 JSON 中的一部分数据并从中重新创建 CoreData 实体将是共享数据而不是共享整个图的更安全、更容易的策略。

  1. 您只能将文件复制到 iCloud 容器中并跨设备共享,但您不能真正直接从容器中使用它或通过 iCloud 进行增量更新。 NSFileManager setUbiquitous 允许将文件移动到 iCloud 容器中。