NSPersistentCloudKitContainer触发CKErrorDomain 12后同步终止,求排查修复方案
CoreData + CloudKit 同步错误 CKErrorDomain 12 排查求助
我用NSPersistentCloudKitContainer实现了CoreData与iCloud的数据同步,近期收到线上用户反馈同步失败,错误码为CKErrorDomain 12。
我通过NSPersistentCloudKitContainer.eventChangedNotification监听同步状态,代码如下:
NotificationCenter.default.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification) .sink(receiveValue: { notification in if let cloudEvent = notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as? NSPersistentCloudKitContainer.Event { let event = SyncEvent(from: cloudEvent) } }) .store(in: &disposables)
用户反馈同步失败时,能看到是CoreData+iCloud导出数据出错,但cloudKitEvent.error仅包含CKErrorDomain 12,没有更多详细信息,根本没法排查问题。
更严重的是,触发这个错误后,应用的同步服务会直接停止,不管是重启App、重启手机还是关闭系统里的iCloud同步,都没法恢复同步功能,只有卸载重装应用才能彻底解决,但这样会导致用户本地未同步的数据丢失。
我的CoreDataStack初始化代码如下:
private func setupContainer(allowCloudKitSync: Bool) -> NSPersistentCloudKitContainer { let container = NSPersistentCloudKitContainer(name: containerName) let privateStoreURL = containerURL.appendingPathComponent(privateStoreName) let privateDescription = NSPersistentStoreDescription(url: privateStoreURL) let privateOpt = NSPersistentCloudKitContainerOptions(containerIdentifier: identifier) privateDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) privateDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) "allowCloudKitSync = \(allowCloudKitSync)".debugLog("CoreDataStack") if allowCloudKitSync { privateDescription.cloudKitContainerOptions = privateOpt } else { privateDescription.cloudKitContainerOptions = nil } container.persistentStoreDescriptions = [privateDescription] container.loadPersistentStores(completionHandler: { [weak self] (storeDescription, error) in if let error = error as NSError? { self?.dbStatePublish.send(.loadError) #if DEBUG "Unresolved error \(error), \(error.userInfo)".debugLog("CoreDataStack") #endif } else { if storeDescription.cloudKitContainerOptions == nil { self?.coreDataState = .local } else { self?.coreDataState = .cloud } "load coredata status = \(String(describing: self?.coreDataState))".debugLog("CoreDataStack") } }) //let options = NSPersistentCloudKitContainerSchemaInitializationOptions() //try? container.initializeCloudKitSchema(options: options) container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy container.viewContext.transactionAuthor = appTransactionAuthorName // Pin the viewContext to the current generation token and set it to keep itself up to date with local changes. container.viewContext.automaticallyMergesChangesFromParent = true do { try container.viewContext.setQueryGenerationFrom(.current) } catch { fatalError("###\(#function): Failed to pin viewContext to the current generation:\(error)") } // Observe Core Data remote change notifications. NotificationCenter.default.addObserver(self, selector: #selector(storeRemoteChange(_:)), name: .NSPersistentStoreRemoteChange, object: container.persistentStoreCoordinator) return container }
有没有人遇到过类似的问题?求帮忙排查,谢谢!
内容的提问来源于stack exchange,提问作者wanbo
相关产品推荐
相关产品推荐

