CloudCore
CloudCore 是一个框架,用原生的 Swift 编写,用于管理 iCloud(CloudKit)和 Core Data 之间的同步。它可以用于 CloudKit 缓存。
特性
- 手动或基于 推送通知 同步。
- 差异同步,只有已更改的对象和值才会上传和下载。CloudCore甚至会在对象内部区分已更改和未更改的值。
- 尊重 Core Data 选项(级联删除、外部存储)。
- 理解和管理 CloudKit 错误,例如
userDeletedZone
、zoneNotFound
、changeTokenExpired
、isMore
。 - 全面覆盖单元和 CloudKit 线上 测试。
- 所有公共方法都是 100% 记录文档。
- 目前仅支持 私有数据库。
工作原理?
CloudCore 是使用“黑箱”架构构建的,因此对您的应用程序来说是不可见的,您只需将几行代码添加到 AppDelegate
中即可启用它。同步和错误处理是自动管理的。
- CloudCore 存储从 CloudKit 传输的 更改令牌,因此只下载已更改的数据。
- 当启用 CloudCore (
CloudCore.enable
) 时,它会从 CloudKit 获取变更数据,并订阅 CloudKit 关于新变更的推送通知。 - 当手动调用
CloudCore.fetchAndSave
或通过推送通知调用时,CloudCore 会从 CloudKit 获取并保存变更数据到 Core Data。 - 当数据写入持久容器(父上下文已保存)时,CloudCore 找到本地更改的数据,并将其上传到 CloudKit。
安装
CocoaPods
CloudCore 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile
pod 'CloudCore', '~> 2.0'
如何提供帮助?
当前框架版本尚未经过深度测试,可能存在错误。如果您可以测试框架,我将非常高兴。如果您发现了错误,请发布 问题。
文档
所有公共方法均使用 XCode 标记 进行文档化,并在 XCode 中提供。该文档的 HTML 版本可在 CocoaDocs 上找到。
快速入门
- 属性类型为
Binary
的recordData
- 属性类型为
String
的recordID
- 修改您的 AppDelegate.swift 文件
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Register for push notifications about changes
application.registerForRemoteNotifications()
// Enable CloudCore syncing
CloudCore.enable(persistentContainer: persistentContainer, errorDelegate: self)
return true
}
// Notification from CloudKit about changes in remote database
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Check if it CloudKit's and CloudCore notification
if CloudCore.isCloudCoreNotification(withUserInfo: userInfo) {
// Fetch changed data from iCloud
CloudCore.fetchAndSave(using: userInfo, to: persistentContainer, error: nil, completion: { (fetchResult) in
completionHandler(fetchResult.uiBackgroundFetchResult)
})
}
}
func applicationWillTerminate(_ application: UIApplication) {
// Save tokens on exit used to differential sync
CloudCore.tokens.saveToUserDefaults()
}
- 在开发环境中第一次运行应用程序,填充Core Data的示例数据并等待同步完成。CloudCore会自动创建所需的CloudKit方案。
服务属性
CloudCore将服务CloudKit信息存储在托管对象中,您需要将其属性添加到您的Core Data模型中。如果找不到要求的属性,该实体将不会被同步。
同步每个实体所需属性
- 属性类型为
Binary
的 Record Data - 属性类型为
String
的 Record ID
您可以以两种方式指定属性名称(您可以在不同的实体中结合这两种方式)。
用户信息
CloudCore首先会在您的模型中查找用户信息以搜索属性,您可以通过指定属性的用户信息键 CloudCoreType
来标记属性为服务属性。值如下
- 值为 Record Data 的
recordData
。 - 值为 Record ID 的
recordID
。
默认名称
最简单的方法是使用默认名称命名属性,因为这不需要指定任何用户信息。
💡 提示
- 您可以随意命名属性,用户信息的值不会改变(您可以创建一个带有用户信息:
CloudCoreType: recordID
的属性myid
) - 我建议将 Record ID 属性标记为
Indexed
,这可以在大数据库中加快更新速度。 - Record Data 属性用于存储只包含系统字段(如时间戳、令牌)的
CKRecord
的存档版本,所以不用担心大小,这里不会存储真实数据。
示例应用程序
您可以在 示例 目录中找到示例应用程序。
如何运行它
- 设置Bundle标识符。
- 检查嵌入式二进制文件路径是否正确(您可以移除并再次添加CloudCore.framework)。
- 如果您正在使用模拟器,请在其上登入iCloud。
如何使用
- +按钮向本地存储添加新对象(这将被自动同步到云端)
- 刷新按钮调用
fetchAndSave
以从云端获取数据。对于模拟器来说,这是一个有用的按钮,因为模拟器无法接收推送通知 - 使用CloudKit仪表板进行更改,并在应用程序中查看更改,并在应用程序中更改并在仪表板中查看。别忘了刷新仪表板页面,因为它不会即时更新数据。
测试
CloudKit对象无法伪造,因此我创建了两种不同类型的测试
-
Tests/Unit
我在这里放置了可以在没有CloudKit连接的情况下执行测试。当您提交拉取请求时,这些测试将执行。 -
Tests/CloudKit
这里定位的是“手动”测试,它们是最重要的测试,只能在不同配置的环境下运行,因为它们与CloudKit和您的Apple ID一起工作。您的账户不会有任何问题,测试仅使用应用私有
CKDatabase
。请在这些测试之前打开拉取请求。要运行它们,您需要
- 更改
TestableApp
的bundle标识符。 - 在模拟器或实际设备上运行
TestableApp
目标。 - 在该设备上配置iCloud:Settings.app → iCloud → 登录。
- 运行
CloudKitTests
,它们连接到TestableApp
,因此CloudKit连接将工作。
- 更改
路线图
- 从alpha状态迁移到beta状态。
- 添加
CloudCore.disable
方法 - 添加清除本地缓存和远程数据库的方法
- 为
limitExceeded
错误添加错误解决程序(按关系分割保存)
作者
可招聘/搬迁。瓦西里·尤里安诺夫,[email protected]