iOS 8 CoreData iCloud 同步一致性出现问题



我有一个使用 xCode 6.3.2 用 Swift 编写的通用应用程序。 目前非常简单,因为当我按下按钮时,会生成一个随机数,然后使用 CoreData 进行存储。 在我实施iCloud之前,这非常有效。 启用 iCloud 后,存储新的随机数并不总是会传播到其他设备上。 它在大多数情况下都是如此,但并非总是如此。

我正在使用iPad Air,iPhone 6 Plus和iPhone 4s进行测试

我正在使用以下三个通知观察器:

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "persistentStoreDidChange", name: NSPersistentStoreCoordinatorStoresDidChangeNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "persistentStoreWillChange:", name: NSPersistentStoreCoordinatorStoresWillChangeNotification, object: managedContext.persistentStoreCoordinator)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "receiveiCloudChanges:", name: NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: managedContext.persistentStoreCoordinator)

这是第三个函数:

func receiveiCloudChanges(notification: NSNotification)
{
    println("iCloud changes have occured")
    dispatch_async(dispatch_get_main_queue())
        {
            self.activityIndicator.startAnimating()
            self.updateLabel.text = "iCloud changes have occured"
            self.managedContext.performBlockAndWait
                { () -> Void in
                    self.managedContext.mergeChangesFromContextDidSaveNotification(notification)
                }
            self.reloadTextViewAndTableView()
            self.activityIndicator.stopAnimating()
        }
}

在托管上下文完成合并之前,我不会尝试更新 UI,并且我在主线程上执行所有操作。 我真的很不知所措,为什么一台设备上的更改仅在大约 90-95% 的时间内显示在第二台或第三台设备上。

作为我反复试验的一部分,当我从测试设备中删除应用程序并重新安装时,有时会显示一条消息,指出iCloud操作正在挂起,但是我等待多长时间并不重要,一旦设备不同步,它们就会保持这种状态。 即使它们不同步,如果我再添加一两个数字,它们仍然会传播到其他设备,但随后我总是会丢失更多数据。 它似乎在大约 90% 的时间内有效。

我使用以下方法来更新 UI:

func reloadTextViewAndTableView()
{
    let allPeopleFetch = NSFetchRequest(entityName: "Person")
    var error : NSError?
    let result = managedContext.executeFetchRequest(allPeopleFetch, error: &error) as! [Person]?
    //Now reload the  textView by grabbing every person in the DB and appending it to the textView
    textView.text = ""
    allPeople = managedContext.executeFetchRequest(allPeopleFetch, error: &error) as! [Person]
    for dude in allPeople
    {
        textView.text = textView.text.stringByAppendingString(dude.name)
    }
    tableView.reloadData()
    println("allPeople.count = (allPeople.count)")
}

我真的在这里停滞不前。 我只是不确定为什么它"通常"有效......

所以我仍然不确定 CoreData 有时会如上所述如何或为什么不同步。 我发现,如果我输入一个接一个的新数字非常快,通常是它发生的时候。

作为解决方法,我在UI中添加了一个按钮,允许用户使用以下选项重新构建NSPersistentStore来强制与iCloud重新同步。

NSPersistentStoreRebuildFromUbiquitousContentOption: true

我宁愿商店始终与所有其他设备保持同步,但至少这样用户永远不会丢失数据。 如果他们注意到他们丢失了他们知道自己在另一台设备上输入的记录,那么他们所要做的就是点击重新同步按钮。

最新更新