| 平台 | 测试 | 覆盖率 |
|---|---|---|
| macOS | ||
| iOS | ||
| tvOS | ||
| watchOS | 仅构建信息 - 敬请期待 |
Stitch 就像它的名字一样,有一些需要注意的棘手部分。
它主要是为我的需求而构建的,我不需要这些,但我并不反对支持那些有意义的需求
在看到那份可怕的缺点列表之后,Stitch 能提供什么呢?
| 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 中定义
serverWins - 这是默认值。 它将服务器记录视为真实记录。clientWins - 这将客户端记录视为真实记录。StitchStore.storeType 的存储类型添加到应用程序的 NSPersistentStoreCoordinator,并将其分配给上一步中创建的属性。 传入适当的选项字典,有关支持的选项的更多信息如下。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)
handlePush。(显示 macOS)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)
}
由 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 中定义
FetchRequestPredicateReplacement NSNumber 布尔值,用于启用在 NSFetchRequests 的 NSPredicates 中替换 NSManagedObjects。 默认为 false。 要求要替换的对象在替换之前保存,否则将抛出错误。 支持替换托管对象:"keyPath == %@"、"keyPath in %@" 和 "%@ contains %@" predicates,以及那些作为子谓词的复合谓词。
SyncConflictResolutionPolicy 是 StitchStore.ConflictPolicy 中一个选项的原始值的 NSNumber。 默认为 StitchStore.ConflictPolicy.serverWins
CloudKitContainerIdentifier 是一个字符串,用于标识如果您的应用程序使用的标识符与您的 Bundle ID 不匹配,则要使用哪个 CloudKit 容器 ID。 默认为使用 CKContainer.default().privateCloudDatabase。 重要的是,您的应用程序在不同的平台上都设置为使用相同的 CloudKit 容器。
ConnectionStatusDelegate 是一个符合 StitchConnectionStatus 的对象,用于询问我们目前是否有互联网连接
ExcludedUnchangingAsyncAssetKeys 是一个字符串数组,指示由于是一个大型 CKAsset 而不应在主循环中同步下载的键。 可以根据应用程序的需求在稍后按请求或按需进行同步下载。 您的包含资产的属性的名称不应与您要同步下载的其他键重叠才能使用此功能。 默认为 nil。
BackingStoreType 是一个字符串,用于定义要使用的后备存储的类型。 默认为 NSSQLiteStoreType,并且针对此类型进行测试。 其他商店可能存在问题。
SyncOnSave 是一个 NSNumber 布尔值,用于指示在告知数据库保存时是否自动同步。 默认为 true。
ZoneNameOption 允许您指定一个字符串用作 CloudKitZone ID 名称。 默认为 StitchStore.SubscriptionInfo.CustomZoneName
SubscriptionNameOption 允许您指定一个字符串用作 CloudKit 订阅名称 ID。 默认为 StitchStore.SubscriptionInfo.SubscriptioName
Xcode 11
Swift 5.1
只需在 Xcode 11 中将 git url 添加到 Swift Package Manager
Stitch 由 Elizabeth Siemer 创建,基于我大量修改的 Seam,作者是 Nofel Mahmood,但它几乎被完全重写了。
在 Twitter 和 GitHub 上关注 Elizabeth,或发送电子邮件至 elizabeth@darkchocolatesoftware.com
Stitch 在 MIT 许可证下可用。 有关更多信息,请参见 LICENSE 文件。