swift - NSPersistentCloudKitContainer:与 App Extension 共享单个数据库
问题描述
我知道这是一个常见的问题,也许以前被问过很多次。我还知道如何通过启用 App Groups 来使用 Core Data 与 App Extensions 共享单个数据库。我现在使用NSPersistentCloudKitContainer
来同步数据(跨 iCloud 设备),效果很好。
但是我想与我的 App Extensions(Today Extension)共享我的数据库,此时 App Groups 将不再有帮助,因为它们是 Apple 描述的不同技术。所以我只是从签名和功能窗格中为容器应用程序和应用程序扩展启用了 iCloud。然后我可以从两个应用容器/扩展访问我的单个数据库,如下所示:
// MARK: - Core Data stack, Shared database
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "MyApp")
// Spotlight search support and history tracking
container.persistentStoreDescriptions.forEach {
$0.setOption(CoreDataSpotlightSearchDelegate.init(forStoreWith: $0, model: container.managedObjectModel), forKey: NSCoreDataCoreSpotlightExporter)
$0.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
// Load persistent store
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
return container
}()
但是,它仅在设备在线时才有效(这是预期的行为),所以我的问题是:
当设备离线使用时,是否可以在应用程序和扩展程序之间共享我的数据库NSPersistentCloudKitContainer
?一些解决方法?
编辑
这是一个非工作版本,我可以访问相同的数据库但没有云同步(没有出现在 CloudKit 仪表板上):
// MARK: - Core Data stack, Shared database
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "MyApp")
// Shared container support
if let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.company.MyApp")?.appendingPathComponent("MyApp.sqlite") {
let persistentStoreDescription = NSPersistentStoreDescription.init(url: url)
container.persistentStoreDescriptions = [persistentStoreDescription]
}
// Spotlight search support and history tracking
container.persistentStoreDescriptions.forEach {
$0.setOption(CoreDataSpotlightSearchDelegate.init(forStoreWith: $0, model: container.managedObjectModel), forKey: NSCoreDataCoreSpotlightExporter)
}
// Load persistent store
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
return container
}()
解决方案
要在应用程序和扩展程序之间共享数据库,您需要完全实现持久历史跟踪;它不像启用商店选项那么简单。有关该功能的介绍,请参阅WWDC 2017 What's New in Core Data at 20:49,另请参阅文档Consuming Relevant Store Changes,特别是“Merge Relevant Transactions into a Context”。
我关于为什么您在使用时没有注意到问题的理论NSPersistentCloudKitContainer
是,当您的商店在线并与云同步时,您受益于云同步在您的应用程序进程中运行并在恢复时编辑商店的副作用turn 导致您的上下文得到更新。
顺便说一句,该NSPersistentHistoryTrackingKey
选项默认设置为NSPersistentCloudKitContainer
具有cloudKitContainerOptions
与默认第一个商店描述类似的商店描述。
推荐阅读
- reactjs - React 项目如何解决 React 依赖项?
- java - 尝试向表中插入数据时出错
- json - 如何在ansible中遍历字典值
- react-native - 防止 iOS 在 React Native TextInput 中将双连字符变成“破折号”
- javascript - 如何获得正确分页的下一个结果
- arrays - UIImage 没有出现在 UIScrollView 中
- java - 有没有办法将不断变化的数组反复传递给 Java Canvas 并让它更新屏幕?
- javascript - 如何改进我的代码,为什么它不运行?
- c++ - 按升序排列值的算法
- c++ - c ++迭代基类和派生类