在异步 iCloud 初始化期间未能完成商店设置

Posted

技术标签:

【中文标题】在异步 iCloud 初始化期间未能完成商店设置【英文标题】:Failed finishing setup for store during asynchronous iCloud initialization 【发布时间】:2015-09-09 02:57:27 【问题描述】:

我正在 Swift 2 中创建一个核心数据堆栈,该堆栈使用 iCloud 使用不同的资源(主要在 Objective-C 中)处理与其他 iDevice 的同步数据。

运行应用程序时,有时会出现以下错误,如果再次运行,错误会消失,但有时会显示应该删除的旧数据:

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 存储库供其他新开发人员使用。

【问题讨论】:

如果您使用的是测试版,那么这很可能是一个错误。我已经看过几次了,但它似乎消失了,事情最终同步正常。 顺便说一句,确保您拥有最新版本的 XCode 7 beta 这方面有什么进展吗?我正在使用 XCode 7 的公共构建,但仍然得到这个 我在 Xcode 7 的发布版本中看到了同样的问题。 我在 Xcode 7.1 中仍然看到同样的问题。在我的应用程序中,我实现了@daleijn 在他的回答中提供的链接中给出的核心数据堆栈。尽管大多数 iCloud 错误确实相当可怕但没有真正的后果,但问题中的错误是唯一导致我的数据停止同步并最终损坏的错误。所以,不幸的是,这个错误确实是真实的。我发现自己处于同样的情况,但仍然无法解决 【参考方案1】:

无法将其作为评论留下,因为在这里写道。找到关于这个问题的回复here

就出现的那些 iCloud 错误而言,它们通常看起来比实际要可怕得多。我的经验是,iCloud 非常擅长在日志中生成许多看起来非常可怕的消息,这些消息实际上并没有表明任何错误。在大多数情况下,错误会在一段时间后自动更正。我有时需要做的最多的干预是在使用 ios 模拟器时,有时你需要重置计算机来修复它。 但是,有些事情可能会导致 iCloud 容器损坏。如果您正在执行大量同步测试,特别是生成大量重复的操作,则 iCloud 容器可能需要较长时间才能正确同步。 您还需要注意,任何(我的意思是)对 Core Data 中保存的信息的任何访问都是从同一个线程处理的。这包括读取从 Core Data 加载的对象。从多个线程访问信息很容易导致损坏,直到您尝试同步容器(或迁移它)才会显现出来。避免这种情况的最好方法是在 iCloud + Core Data 堆栈上使用 performBlockperformBlockAndWait 方法。这些方法保证操作(读取或写入)将发生在同一个线程上,以防止数据损坏。

【讨论】:

以上是关于在异步 iCloud 初始化期间未能完成商店设置的主要内容,如果未能解决你的问题,请参考以下文章

mac上显示“未能载入偏好设置面板“MySQL”。”

未能加载视图状态。正在向其中加载视图状态的控件树必须与前一请求期间用于保存视图状态的控件树相匹配。例如,当以动态方式添加控件时,在回发期间添加的控件必须与在初始请求期间添加的控件的类型和位置相匹配

将 iCloud 商店迁移到本地

iCloud 已关闭,但设置仍显示正在上传的数据

iCloud Core 数据同步设置

在最新检查期间未能捕获任务“:app:preDebugBuild”属性“compileManifests”的输入文件指纹