简体   繁体   English

异步iCloud初始化期间存储的完成设置失败

[英]Failed finishing setup for store during asynchronous iCloud initialization

I am in the process of creating a core data stack in Swift 2 that handles syncing data with other iDevices using iCloud using different resources (Mostly in Objective-C). 我正在使用Swift 2创建核心数据堆栈,该堆栈使用不同的资源(主要使用Objective-C)使用iCloud处理与其他iDevices的数据同步。

When running the app I sometimes get the following error, and if I run it again the error goes but sometimes displays old data that was supposed to be deleted: 运行应用程序时,我有时会收到以下错误,如果我再次运行它会出错,但有时会显示应该删除的旧数据:

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:

Core Data Stack 核心数据堆栈

// 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
}()

Does anybody understand why this is occurring and how I can resolve the error ? 有人理解为什么会这样,以及我如何解决错误? I really appreciate feedback as I am hoping to create a public GitHub repository for other new developers to use. 我非常感谢您的反馈,因为我希望为其他新开发人员创建一个公共GitHub存储库。

Couldn't leave it as a comment, cuz wrote here. Cuz在这里写道,不能把它留作评论。 Found reply about this issue here 在这里找到关于此问题的回复

In terms of those iCloud errors that appear, they generally look a lot scarier than they are. 就出现的那些iCloud错误而言,它们通常看起来比它们更可怕。 My experience has been that iCloud is great at generating a lot of very scary looking messages in the log that don't actually signal anything is wrong. 我的经验是,iCloud非常善于在日志中生成大量非常可怕的消息,这些消息实际上并不表示任何错误。 In most cases the errors automatically correct themselves after a time. 在大多数情况下,错误会在一段时间后自动纠正。 The most intervention I have needed to do at times has been when using the iOS simulator where at times you need to reset the computer to fix it. 我有时需要做的最多干预是使用iOS模拟器,有时你需要重置计算机来修复它。 However, there are some things that can cause iCloud containers to become corrupted. 但是,有些事情可能导致iCloud容器损坏。 If you are performing a lot of synchronisation testing, in particular operations that generate a lot of duplicates, it can take an extended time for the iCloud container to properly sync. 如果您正在执行大量同步测试,特别是生成大量重复项的操作,则iCloud容器可能需要较长时间才能正确同步。 You also need to be careful that any, and I do mean any, accessing of the information held in Core Data is handled from the same thread. 您还需要小心任何,我的意思是,访问Core Data中保存的信息是从同一个线程处理的。 That includes reading from the objects that you have loaded from Core Data. 这包括从您从Core Data加载的对象中读取。 Accessing the information from multiple threads can very easily cause corruption that does not manifest until you try to sync the container (or migrate it). 从多个线程访问信息很容易导致在您尝试同步容器(或迁移容器)之前不会显示的损坏。 The best way to avoid that is to use the performBlock and performBlockAndWait methods on the iCloud + Core Data stack. 避免这种情况的最佳方法是在iCloud + Core Data堆栈上使用performBlockperformBlockAndWait方法。 Those methods guarantee that the operations (read or write) will happen on the same thread to prevent data corruption. 这些方法保证操作(读或写)将在同一线程上发生,以防止数据损坏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM