我正在使用Swift 2创建核心数据堆栈,该堆栈使用不同的资源(主要使用Objective-C)使用iCloud处理与其他iDevices的数据同步。
运行应用程序时,我有时会收到以下错误,如果我再次运行该错误,但有时会显示应该删除的旧数据:
2015-09-08 22:49:31.104 APPNAME[5606:418539]
-[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](874): CoreData: Ubiquity:
nobody~sim73E13D94-AB95-59FB-AF18-ADC7BC05B47B:APPNAMEStore Using local
storage: 1 for new NSFileManager current token <766b5e5c 3c205110
52c05248 38a47bd9 aca1ee87> 2015-09-08 22:49:31.185
APPNAME[5606:418593] -[PFUbiquitySetupAssistant
finishSetupForStore:error:](1125): CoreData: Ubiquity: CoreData:error: Caught Exception Unable to resolve mismatching KVs with
userInfo {
PFUbiquitySetupDoFork = 1; } in -finishSetupForSet:error: 2015-09-08 22:49:31.243 APPNAME[5606:418593] -[PFUbiquitySetupAssistant
finishSetupWithRetry:](829): CoreData: Ubiquity: <PFUbiquitySetupAssistant: 0x7f97b3328320>: Retrying after delay: 60
Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={failed finishing setup for store during asynchronous iCloud
initialization=file:///Users/USER/Library/Developer/CoreSimulator/Devices/19DE5FBA-9248-410D-9264-6B434B30F8CA/data/Containers/Data/Application/5B174D0D-C80D-4362-90EE-DC640F907962/Documents/CoreDataUbiquitySupport/nobody~sim73E13D94-AB95-59FB-AF18-ADC7BC05B47B/APPNAMEStore/DD2F75D5-FEAF-482A-A896-657936AFCFCD/store/APPNAME.sqlite}
2015-09-08 22:50:31.288 APPNAME[5606:418966] -[PFUbiquitySetupAssistant finishSetupForStore:error:](1125): CoreData: Ubiquity: CoreData: error: Caught Exception Unable to resolve mismatching KVs with userInfo {
PFUbiquitySetupDoFork = 1; } in -finishSetupForSet:error: 2015-09-08 22:50:31.289 APPNAME[5606:418966]
-[PFUbiquitySetupAssistant
finishSetupWithRetry:](829): CoreData: Ubiquity: <PFUbiquitySetupAssistant: 0x7f97b3328320>: Retrying after delay: 120 Error Domain=NSCocoaErrorDomain Code=134080 "(null)" UserInfo={failed finishing setup for store during asynchronous iCloud
initialization=file:///Users/USER/Library/Developer/CoreSimulator/Devices/19DE5FBA-9248-410D-9264-6B434B30F8CA/data/Containers/Data/Application/5B174D0D-C80D-4362-90EE-DC640F907962/Documents/CoreDataUbiquitySupport/nobody~sim73E13D94-AB95-59FB-AF18-ADC7BC05B47B/APPNAMEStore/DD2F75D5-FEAF-482A-A896-657936AFCFCD/store/APPNAME.sqlite}
2015-09-08 22:52:31.333 APPNAME[5606:420217] -[PFUbiquitySetupAssistant finishSetupForStore:error:](1125): CoreData: Ubiquity: CoreData: error: Caught Exception Unable to resolve mismatching KVs with userInfo {
PFUbiquitySetupDoFork = 1; } in -finishSetupForSet:error:
核心数据堆
// MARK: - Core Data stack
// This handles the updates to the data via iCLoud updates
func registerCoordinatorForStoreNotifications (coordinator : NSPersistentStoreCoordinator) {
let nc : NSNotificationCenter = NSNotificationCenter.defaultCenter();
nc.addObserver(self, selector: "StoresWillChange:",
name: NSPersistentStoreCoordinatorStoresWillChangeNotification,
object: coordinator)
nc.addObserver(self, selector: "StoresDidChange:",
name: NSPersistentStoreCoordinatorStoresDidChangeNotification,
object: coordinator)
nc.addObserver(self, selector: "StoreChangedUbiquitousContent:",
name: NSPersistentStoreDidImportUbiquitousContentChangesNotification,
object: coordinator)
}
// Subscribe to NSPersistentStoreCoordinatorStoresWillChangeNotification
// most likely to be called if the user enables / disables iCloud
// (either globally, or just for your app) or if the user changes
// iCloud accounts.
func StoresWillChange (notification:NSNotification) {
managedObjectContext.performBlock { () -> Void in
if self.managedObjectContext.hasChanges {
do {
try self.managedObjectContext.save()
} catch {
print("error saving Managed Object Context in AppDelegate")
}
} else{
// drop any manged object refrences
self.managedObjectContext.reset()
}
}
}
// Subscribe to NSPersistentStoreCoordinatorStoresDidChangeNotification
func StoresDidChange(notification: NSNotification) {
NSLog("storesDidChange posting notif");
NSNotificationCenter.defaultCenter().postNotificationName("storeDidChange", object: nil)
}
func mergeChanges(notification: NSNotification) {
NSLog("mergeChanges notif:\(notification)")
self.managedObjectContext.performBlock {
self.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
}
}
func StoreChangedUbiquitousContent(notification: NSNotification) {
self.mergeChanges(notification);
}
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.USER.swift2-iCloud" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1]
}()
lazy var managedObjectModel: NSManagedObjectModel = {
let modelURL = NSBundle.mainBundle().URLForResource("APPNAME", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("APPNAME.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
// iCloud store
var storeOptions = [NSPersistentStoreUbiquitousContentNameKey : "APPNAMEStore",NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
do {
try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: NSURL.fileURLWithPath(url.path!), options: storeOptions)
} catch var error1 as NSError {
error = error1
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
} catch {
fatalError()
}
self.registerCoordinatorForStoreNotifications (coordinator!)
return coordinator
}()
有人理解为什么会这样,以及我如何解决错误?我非常感谢您的反馈,因为我希望为其他新开发人员创建一个公共GitHub存储库。
答案 0 :(得分:0)
无法将其留作评论,cuz在此写道。找到关于此问题的回复here
就出现的那些iCloud错误而言,它们通常看起来比它们更加可怕。我的经验是,iCloud非常善于在日志中生成大量非常可怕的消息,这些消息实际上并不表示任何错误。在大多数情况下,错误会在一段时间后自动纠正。我有时需要做的最多干预是使用iOS模拟器,有时你需要重置计算机来修复它。
但是,有些事情可能导致iCloud容器损坏。如果您正在执行大量同步测试,特别是生成大量重复项的操作,则iCloud容器可能需要较长时间才能正确同步。
您还需要小心任何,我的意思是,访问Core Data中保存的信息是从同一个线程处理的。这包括从您从Core Data加载的对象中读取。从多个线程访问信息很容易导致在您尝试同步容器(或迁移容器)之前不会显示的损坏。避免这种情况的最佳方法是在iCloud + Core Data堆栈上使用performBlock
和performBlockAndWait
方法。这些方法保证操作(读或写)将在同一个线程上发生,以防止数据损坏。