识别 iCloud coreData 更新:良好实践

Posted

技术标签:

【中文标题】识别 iCloud coreData 更新:良好实践【英文标题】:Identifying iCloud coreData updates: good practice 【发布时间】:2014-08-28 00:14:28 【问题描述】:

我有使用 iCloud 和 CoreData(相同容器)的应用程序(ios 和 Mac)。每个设备都可以创建或更新数据。当设备创建或更新托管对象时,其他设备最终需要执行与托管对象相关的特定操作(与 UI 无关)。

例如,

设备 1 离线, 设备 2 在线并更改了托管对象。 稍后,设备 1 上线:它必须识别已创建和更新的托管对象才能执行某些操作。

我的问题:我可以依靠通知系统来实现吗? (NSPersistentStoreCoordinatorStoresDidChangeNotificationNSPersistentStoreDidImportUbiquitousContentChangesNotification

依赖通知意味着我必须确定当数据发生变化时,通知最终会到达每台设备上的我的应用程序。 特别是,本地存储上的数据同步是否仅在应用程序运行时执行(从而希望确保如果应用程序注册得足够快,通知将到达应用程序)?

或者是否应该使用我自己的机制来实现这种类型的要求,以识别商店中的修改? (这会使模型复杂化,因为每个设备都必须知道它已经处理了对特定托管对象的更新)

编辑:看到这句话here:

在首次设置后和在您的应用运行时,Core Data 导入更改从其他对等方持续到 iCloud。

这告诉我通知是可靠的。

【问题讨论】:

【参考方案1】:

根据我的经验,通知是可靠的。来自 iCloud 的更改只会在您的应用程序运行时同步。该同步也只会在您添加了相应的持久存储之后才会发生。 (即,您在 Persistent Store Coordinator 上调用了 addPersistentStoreWithType)。

我总是在添加我的持久存储之前注册通知(代码如下所示)。这样您就可以确定自己会收到相关通知。

// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
    if (_persistentStoreCoordinator != nil) 
        return _persistentStoreCoordinator;
    

    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSNotificationCenter* notificationCentre = [NSNotificationCenter defaultCenter];

    [notificationCentre addObserver:self
                           selector:@selector(CoreData_StoresWillChange:)
                               name:NSPersistentStoreCoordinatorStoresWillChangeNotification
                             object:coordinator];
    [notificationCentre addObserver:self
                           selector:@selector(CoreData_StoresDidChange:)
                               name:NSPersistentStoreCoordinatorStoresDidChangeNotification
                             object:coordinator];
    [notificationCentre addObserver:self
                           selector:@selector(CoreData_StoreDidImportUbiquitousContentChanges:)
                               name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
                             object:coordinator];

    NSMutableDictionary* workingOptions = [self.storeOptions mutableCopy];

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:workingOptions error:&error]) 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    

    return _persistentStoreCoordinator;

【讨论】:

感谢您的回答。关于此语句的一个问题:我总是在添加我的持久存储之前注册通知(代码如下所示)。如果注册是在同一个队列执行循环中完成的,在添加store之后,真的会漏掉通知吗? 我相信在这种情况下您不太可能错过通知。但是,iCloud 同步确实在它自己的线程上运行。时间窗口可能太窄了,您永远不会错过任何通知,但我更愿意谨慎行事。 我似乎完全遵循了上述模式。只要只有一台设备处于离线状态,一切似乎都可以正常工作。但是,当两个设备都处于离线状态并且将新对象添加到商店时,当两个设备都重新在线时不会收到通知,因此不会发生同步。但是,我不确定是否根本没有发出通知,因为设备一处于离线状态,或者设备二是否无法接收到通知。一旦两个设备都重新联机,至少什么都不会收到。感谢您的任何建议!

以上是关于识别 iCloud coreData 更新:良好实践的主要内容,如果未能解决你的问题,请参考以下文章

如何在发布更新时启用 iCloud 并迁移 Core Data?

Core Data + iCloud 如何处理来自云端的数据更新

Core Data + iCloud,更改通知插入和删除关系中的对象但不更新关系中现有实体的属性

核心数据 - iCloud 行为

告知 iCloud 何时没有更多待处理的 Core Data 更新更改

是否需要为 iCloud Drive 更新 iOS 7 iCloud 应用程序?