Stitch,一个 CoreData 到 CloudKit 的同步库

License Platforms Language GitHub tag (latest SemVer)

平台 测试 覆盖率
macOS Tests Coverage
iOS Tests Coverage
tvOS Tests Coverage
watchOS 仅构建信息 - 敬请期待

Stitch 是一个用于将 CoreData 存储同步到 CloudKit 的框架,并向后兼容比 CloudKit+CoreData 更早的操作系统。

这是一个正在进行的项目。 它可以构建,可以同步,并且有很多测试,但并非所有失败条件和选项都已覆盖。

警告

Stitch 就像它的名字一样,有一些需要注意的棘手部分。

它主要是为我的需求而构建的,我不需要这些,但我并不反对支持那些有意义的需求

那它能做什么呢?

在看到那份可怕的缺点列表之后,Stitch 能提供什么呢?

CoreData 到 CloudKit

属性

CoreData CloudKit
日期 日期/时间
数据 字节
外部存储数据 CKAsset
字符串 字符串
Int16 Int(64)
Int32 Int(64)
Int64 Int(64)
小数 双精度浮点数
单精度浮点数 双精度浮点数
布尔值 Int(64)
NSManagedObject 引用

关系

CoreData 关系 在 CloudKit 上的转换
一对一 一对一关系在 CloudKit 容器中转换为 CKReferences。
一对多 不会显式创建一对多关系,Stitch 仅在 CloudKit 中创建和管理一对一关系,然后在同步下载时将其转换回来。
示例 -> 如果 Employee 与 Department 存在一对一关系,而 Department 与 Employee 存在一对多关系,则 Stitch 仅将 employee 链接到 CloudKit 中的 Department。 在同步期间,它将这些转换回本地存储
多对多 Stitch 不直接支持这些。 但是,您可以使用链接表来创建它们

注意: 您必须在应用程序的 CoreData 模型中创建反向关系,否则 Stitch 无法将 CoreData 模型转换为 CloudKit 记录。 可能会发生意外错误和数据损坏。

同步

Stitch 使 CoreData 存储与 CloudKit 服务器保持同步。

同步完成后,您必须将更改集成到您的 UI 中。 稍后会详细介绍。

冲突解决策略

如果发生任何同步冲突,Stitch 会公开 2 种冲突解决策略。 在 StitchStore.ConflictPolicy 中定义

如何使用

do {
   let store  = try coordinator.addPersistentStoreWithType(StitchStore.storeType,
                                                           configuration: nil,
                                                           URL: url,
                                                           options: options) as? StitchStore
   store?.triggerSync(.storeAdded)
} catch {
   print("There was an error adding the store! \(error)")
}
UIApplication.shared.registerForRemoteNotifications()
NSApp.registerForRemoteNotifications(matching: .alert)
func application(application: UIApplication, 
                 didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) 
{
   self.smStore?.handlePush(userInfo: userInfo)
}
NotificationCenter.default.addObserver(self,
                                       selector: #selector(cloudKitSyncComplete),
                                       name: StitchStore.Notifications.DidFinishSync,
                                       object: nil)
func realObjectsFromCloudKitSyncIDs(ids: Array<NSManagedObjectID>) -> Set<NSManagedObject> {
   return Set<NSManagedObject>(ids.compactMap { persistentContainer.viewContext.object(with: $0) })
}
@objc func cloudKitSyncComplete(note: NSNotification) {
   let noteInserted = note.userInfo?[NSInsertedObjectsKey] as? Array<NSManagedObjectID> ?? []
   let noteDeleted = note.userInfo?[NSDeletedObjectsKey] as? Array<NSManagedObjectID> ?? []
   let noteUpdated = note.userInfo?[NSUpdatedObjectsKey] as? Array<NSManagedObjectID> ?? []
   if noteInserted.count == 0 && noteDeleted.count == 0 && noteUpdated.count == 0 {
      return
   }

   let objectArrays = [NSInsertedObjectsKey: realObjectsFromCloudKitSyncIDs(ids: noteInserted),
                       NSDeletedObjectsKey: realObjectsFromCloudKitSyncIDs(ids: noteDeleted),
                       NSUpdatedObjectsKey: realObjectsFromCloudKitSyncIDs(ids: noteUpdated)]
   let modifiedNote = Notification(name: .NSManagedObjectContextDidSave,
                                   object: note.object,
                                   userInfo: objectArrays)
   persistentContainer.viewContext.mergeChanges(fromContextDidSave: modifiedNote)
}

关于在 Objective-C 项目中使用 Swift Package Manager 的 Stitch 的一些说明

由 Swift Package Manager 管理的 Swift 目标无法直接导入到 Obj-C 代码中。 您将需要使用一些 swift 代码来处理 Stitch 模块中的内容。

如果您想在框架中使用它,例如可能在主应用程序和扩展程序之间共享的框架,Xcode 尝试将其作为导入添加到框架生成的 [ModuleName]-Swift.h,这将导致错误。 这可以通过向框架目标添加私有模块映射来解决。 使用扩展名 .modulemap 创建一个文件,内容为

module Stitch {
   export *
}

然后在构建设置中将模块映射的项目相对路径放在设置 MODULEMAP_PRIVATE_FILE 中。 无论是在框架中还是在链接到它的应用程序中,Objective-C 都无法访问 Stitch,但无论是在框架中还是在应用程序中,Swift 都可以使用它。

(可能还有更好的处理方法,但这对我来说有效)

选项

StitchStore.Options 中定义

要求

Xcode 11

Swift 5.1

支持

入门

安装

只需在 Xcode 11 中将 git url 添加到 Swift Package Manager

鸣谢

Stitch 由 Elizabeth Siemer 创建,基于我大量修改的 Seam,作者是 Nofel Mahmood,但它几乎被完全重写了。

联系方式

TwitterGitHub 上关注 Elizabeth,或发送电子邮件至 elizabeth@darkchocolatesoftware.com

许可证

Stitch 在 MIT 许可证下可用。 有关更多信息,请参见 LICENSE 文件。