【发布时间】:2020-09-03 10:55:48
【问题描述】:
我正在向我现有的应用程序添加 Today Extension。我添加了一个 App Group 并使用此 post 成功将我的 Core Data 的数据迁移到 App Group 的商店。我的应用同时使用 NSPersistentCloudKitContainer(当 iCloud 开启时)和 NSPersistentContainer(iCloud 关闭)。虽然两个容器中的数据都成功迁移,但在使用 NSPersistentCloudKitContainer 时,我不再能够在我的设备之间同步。在控制台中,我收到这两个错误:
CoreData: 错误: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(837): : 无法为商店设置 CloudKit 集成: (URL: file://path/name.sqlite)
Error Domain=NSCocoaErrorDomain Code=134060 “发生核心数据错误。” UserInfo={NSLocalizedFailureReason=镜像委托无法初始化,因为它的存储已从协调器中删除。}
第一条错误消息的路径是切换到 App Groups 之前 oldURL 的路径。 所以我相信我只需要告诉 iCloud 不要尝试在该商店位置集成 CloudKit 并使用 App Group 的商店位置。
但我不知道该怎么做。有人可以帮忙吗?
核心数据代码:
class CoreDataManager {
static let sharedManager = CoreDataManager()
private init() {}
lazy var persistentContainer: NSPersistentContainer = {
var useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
//Get the correct container
let containerToUse: NSPersistentContainer?
if useCloudSync {
containerToUse = NSPersistentCloudKitContainer(name: "App")
} else {
containerToUse = NSPersistentContainer(name: "App")
}
guard let container = containerToUse else {
fatalError("Couldn't get a container")
}
//Set the storeDescription
let storeURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.App")!.appendingPathComponent("\(container.name).sqlite")
var defaultURL: URL?
if let storeDescription = container.persistentStoreDescriptions.first, let url = storeDescription.url {
defaultURL = FileManager.default.fileExists(atPath: url.path) ? url : nil
}
if defaultURL == nil {
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeURL)]
}
let description = container.persistentStoreDescriptions.first else {
fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
if !useCloudSync {
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
//migrate from old url to use app groups
if let url = defaultURL, url.absoluteString != storeURL.absoluteString {
let coordinator = container.persistentStoreCoordinator
if let oldStore = coordinator.persistentStore(for: url) {
do {
try coordinator.migratePersistentStore(oldStore, to: storeURL, options: nil, withType: NSSQLiteStoreType)
} catch {
print("Hey Listen! Error migrating persistent store")
print(error.localizedDescription)
}
// delete old store
let fileCoordinator = NSFileCoordinator(filePresenter: nil)
fileCoordinator.coordinate(writingItemAt: url, options: .forDeleting, error: nil, byAccessor: { url in
do {
try FileManager.default.removeItem(at: url)
} catch {
print("Hey Listen! Error deleting old persistent store")
print(error.localizedDescription)
}
})
}
}
}
return container
}
}
【问题讨论】:
-
这可以更改默认URL以开始使用完美的应用程序组,但它会破坏iCloud中所有数据的迁移。
-
@ap123 运气好吗?
-
我也遇到了同样的问题。迁移似乎工作正常,但 CloudKit 出现了问题,之后没有任何内容发送到 iCloud。
-
我也看到了同样的问题 - 我开始相信这是 Apple CloudKit 框架中的一个实际错误 - 有人提交了雷达吗?
标签: swift xcode core-data ios-app-group nspersistentcloudkitcontainer