ios - Core Data + iCloud Sync 确实改变了商店通知不刷新 UI

标签 ios swift macos core-data icloud

我无法处理这个问题,我正在尝试将 iCloud 和核心数据集成到我的应用程序中,但我坚持使用 iCloud 同步部分。

我的完整场景:

  1. 使用初始数据播种的本地核心数据存储
  2. 稍后该应用会询问用户有关 iCloud 或本地数据存储的信息
  3. 如果用户选择 iCloud,当前本地存储迁移到 iCloud 存储
  4. 迁移后,上下文和持久存储协调器将重新加载 iCloud Store
  5. 从新上下文重新获取数据(这里有问题)

如果我们去掉关于迁移的讨论并专注于使用 iCloud 加载持久存储协调器,我认为问题与
NSPersistentStoreCoordinatorStoresDidChangeNotification 事件。

我就是不明白。在我阅读的每篇文章中,我都会看到类似这样的内容:“在此处重新加载您的 UI”。但这对我不起作用。

重载协调器函数

func configureContext() -> NSManagedObjectContext? {
    // Create the coordinator and context
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)

    //remove all observers from "previous" coordinator
    deregisterForStoreChanges()
    //and register them for new one
    registerObservers(persistentStoreCoordinator: coordinator)

    do {

        //storeSettings.url = applicationDocumentsDirectory.URLByAppendingPathComponent("iCloud.sqlite")
        //storeSettings.options = [NSPersistentStoreUbiquitousContentNameKey:"iCloudProject"]

        try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeSettings.url, options: storeSettings.options)

    } catch {
        //Here was standard error handler I didn't changed it, but removed for listing
        abort()
    }
    persistentStoreCoordinator = coordinator

    let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = coordinator

    //not quite sure about the next string, didn't test it yet
    managedObjectContext.mergePolicy = NSMergePolicy(mergeType:NSMergePolicyType.MergeByPropertyStoreTrumpMergePolicyType )

    //tried to refetch my records here but, with no luck.
    //refetchUIRecords()
    return managedObjectContext
}

还有我的 NSPersistentStoreCoordinatorStoresDidChangeNotification 事件函数

func persistentStoreCoordinatorDidChangeStores(notification:NSNotification){

    if notification.userInfo?[NSAddedPersistentStoresKey] != nil {
        print("-----------------------")
        print("ADDED")
        print("-----------------------")
        //deduplicateRecords()

        //if iCloud -> refetch UI
        if NSUserDefaults.standardUserDefaults().boolForKey("iCloud"){
            self.createTimer()
        }
    }
    print("Did Change")

}

创建定时器函数只是一个在实际重新获取和刷新 UI 之前等待 1 秒的函数。

问题

当我们从我的场景到达第 4 步并调用 configureContext 函数时, 我在控制台中看到了这个:

2016-04-12 13:31:27.749 TestingiCloudProject[2052:1142902] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](898): CoreData: Ubiquity:  mobile~567404C0-9D84-4C07-A0F8-D25832CB65D8:iCloudProject
Using local storage: 1 for new NSFileManager current token <ef7a917f bca47ecf 5d58862d cbe9998d 7e53e5ea>
Did Change
Did Change
-----------------------
ADDED
-----------------------
Timer
Did Change
Refetch
Refetching...
Number of records after fetch: 1 //must be more than 1 
2016-04-12 13:31:30.090 TestingiCloudProject[2052:1143055] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](898): CoreData: Ubiquity:  mobile~567404C0-9D84-4C07-A0F8-D25832CB65D8:iCloudProject
Using local storage: 0 for new NSFileManager current token <ef7a917f bca47ecf 5d58862d cbe9998d 7e53e5ea>

如您所见,我的提取请求在 Using local storage: 0 之前执行,这就是为什么我从本地存储(1 条记录)而不是 iCloud(包含超过 1 条)接收记录。

我不知道什么时候重新获取我的记录。我从这个 great source 中获取计时器部分对于所有想了解更多有关 Core Data 和 iCloud 的人。 但是,1 秒是不够的,2 秒是我想要的,但是如果 iCloud 存储比我的大,或者网络连接比我的差,我认为计时器不是办法。

我希望有人已经面对过这个微不足道的问题。

编辑

我没有从 Apple 开发论坛和 SO 找到任何帮助,所以我激活了我的代码技术支持 token ,我希望他们能帮助我。一旦我解决了我的问题,我就会写一个答案。但是,如果阅读此问题的您知道可能的答案,请立即发布。

最佳答案

还有一个通知 NSPersistentStoreDidImportUbiquitousContentChangesNotification,只要从普遍存在的内容存储中导入数据,持久存储协调器就会触发该通知。在这里您可以将更改与您的 NSManagedObjectContext 合并。

When the ubiquity container receives changes from iCloud, Core Data posts an NSPersistentStoreDidImportUbiquitousContentChangesNotification notification. This notification’s userInfo dictionary is structured similarly to that of an NSManagedObjectContextDidSaveNotification notification except for that it contains NSManagedObjectID instances rather than NSManagedObject instances. Therefore you can merge in changes from other peers in the same way that you merge changes from other managed object contexts. Call mergeChangesFromContextDidSaveNotification: on your managed object context, passing in the notification object posted by Core Data.

https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingSQLiteStoragewithiCloud/UsingSQLiteStoragewithiCloud.html

关于ios - Core Data + iCloud Sync 确实改变了商店通知不刷新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36572296/

相关文章:

iphone - 如何将我的应用链接到 App Store 开发者页面?

ios - void 函数 Swift3 中出现意外的非 void 返回值

python - 很好地终止后台python脚本

c++ - 在 C++ 项目中静态链接 MySQL (Mac OS X, g++, Eclipse)

swift - MacOS 应用程序可以在 Bundle.main 中创建一个新文件吗?

iphone - 硬件音量按钮更改应用程序音量

iphone - 将 UIImage 用于 CGContextSetFillColorWithColor 时突然出现内存峰值

ios - 如何使用 SiriKit 通过 Web 服务发送数据?

swift - 将 'UnsafePointer<Void>' 重铸为 'CFHTTPMessageRef'

ios - UITableVIew 无法正确渲染 UITableViewCell