iOS 7 中的 iCloud、Core Data 和来自 Web 服务的数据

Posted

技术标签:

【中文标题】iOS 7 中的 iCloud、Core Data 和来自 Web 服务的数据【英文标题】:iCloud, Core Data, and data from web services in iOS 7 【发布时间】:2014-04-04 13:14:26 【问题描述】:

我正在编写一个非常简单的应用程序,用于跟踪、存储和组织来自 iTunes 和 RottenTomatoes 的电影。我把电影放在一个大的后面,通常一次大约 150 部电影。然后,用户可以查看提要并将电影添加到自定义列表中。

我遇到的问题是从网络中提取数据并与 iCloud 同步,从而产生电影的副本。

我一直在考虑将电影提要放入本地存储(从 iCloud 中删除),然后在单独的 iCloud 核心数据存储中创建列表和其他用户值,甚至使用 iCloud 键值存储(尽管保存电影列表可能会很粗糙)。

这是我第一个使用 iCloud 的应用程序,所以我使用了来自 this objc.io article 的一些样板文件。我做了一些修改,因为我的网络同步使用后台 NSManagedObjectContext 来完成这项工作。后台 MOC 保存,然后我的主 MOC 合并更改。UI 主要是 NSFetchedResultsControllers,因此整个系统可以无缝运行。

这里是一些处理 iCloud NSNotifications 的代码

// happens when the main MOC saves
- (void)managedObjectContextDidSaveNotification:(NSNotification *)notification 
    @synchronized(self) 
        NSManagedObjectContext *moc = self.backgroundManagedObjectContext;

        [moc performBlock:^
            [moc mergeChangesFromContextDidSaveNotification:notification];
        ];
    


// happens when the bg MOC saves
- (void)backgroundManagedObjectContextDidSaveNotification:(NSNotification *)notification 
    @synchronized(self) 
        NSManagedObjectContext *moc = self.managedObjectContext;

        [moc performBlock:^
            [moc mergeChangesFromContextDidSaveNotification:notification];
        ];
    


- (void)persistentStoreDidImportUbiquitousContentChanges:(NSNotification *)notification 
    @synchronized(self) 
        NSManagedObjectContext *moc = self.managedObjectContext;

        [moc performBlock:^
            [moc mergeChangesFromContextDidSaveNotification:notification];
        ];
    


- (void)storesWillChange:(NSNotification *)notification 
    NSManagedObjectContext *moc = self.managedObjectContext;

    [moc performBlockAndWait:^            
        NSError *error = nil;
        if ([moc hasChanges] && [moc save:&error]) 
            DDLogInfo(@"MOC saved succesfully");
        
        else 
            DDLogError(@"Error saving MOC: %@",error);
        
    ];


- (void)storesDidChange:(NSNotification *)notification 

我原本以为在 iCloud 完成合并更改后我可以添加一些逻辑,但这看起来不太可靠,因为我可能最终陷入设备之间的更改循环。

对如何实现这一点有任何想法吗?我敢肯定人们之前已经这样做过,我只是找不到任何有用的资源。

【问题讨论】:

【参考方案1】:

如果我正确理解您的情况,用户可能会同时在两台不同的设备上下载同一部电影,并且在同步后,您拥有该电影的副本。

对于这种情况,Apple 的建议只是在任何 iCloud 合并后进行重复数据删除。您执行 fetch 以查找具有相同电影 id 的对象,并以确定的方式对重复项进行排序,然后删除一个。如果您不对它们进行排序,您可能会在一台设备上删除一个对象,在另一台设备上删除一个不同的对象,最终没有对象。

本文有求重的高效代码:http://www.atomicbird.com/blog/icloud-complications-part-2

如果您不喜欢整个合并后的重复数据删除,TICDS 和 Ensembles 等框架允许您提供全局 ID,从而消除重复数据删除的必要性。 (披露:我开发 Ensembles)

【讨论】:

那么通过排序,是否会避免任何一种“删除循环”,即一台设备删除 dup a,另一台设备删除 dup b,它们同步 a 和 b,然后重复?理论上,两个设备都会删除 dup a? 是的。这个想法是他们都应该删除相同的东西。如果发生这种情况,不应该有任何乒乓球或数据丢失。

以上是关于iOS 7 中的 iCloud、Core Data 和来自 Web 服务的数据的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7 iCloud 和(启用/禁用)Core Data - 永无止境的故事

iCloud Core Data iOS 6 到 iOS 7 最初是空的本地后备存储

Core Data iCloud 获取有时不会产生数据(iOS)

iOS Core Data iCloud 同步 - 可选

iOS、Core Data 和 iCloud - 切换上下文

iOS7 Core Data 和 iCloud 作为备份。用户的观点