【问题标题】:How to sync data from web service with Core Data?如何将来自 Web 服务的数据与 Core Data 同步?
【发布时间】:2014-02-07 07:42:03
【问题描述】:

我正在尝试以一种简单的方式从网络服务同步我的数据。我使用 AFNetworking 下载我的数据,并在每个对象上使用唯一标识符,我想插入、删除或更新该数据。

问题在于,使用 Core Data,您必须在 NSObjectManagedContext 中实际插入对象来实例化 NSManagedObjects。像这样:

MyModel *model = (MyModel *)[NSEntityDescription insertNewObjectForEntityForName:@"MyModel" inManagedObjectContext:moc];
model.value = [jsonDict objectForKey:@"value"];

因此,当我从 Web 服务获取数据时,我会立即将它们插入到 Core Data 中。所以没有真正的同步:我只是事先删除所有内容,然后插入从我的网络服务返回的内容。

我想有更好的方法可以做到这一点,但我不知道怎么做。有什么帮助吗?

【问题讨论】:

  • 我在这里回答了一个类似的问题:stackoverflow.com/questions/5035132/…希望它有所帮助。
  • 通常我希望在创建新对象之前尝试查找现有对象,这样我就可以更新而不是替换。
  • 您的问题没有简单的答案。将远程服务器的数据与可能长时间离线的移动设备同步,实际上是一个“难题”。我敢说,您可以在网络(以及 SO)中找到的所有“简单”解决方案、建议和答案在实际场景中不起作用,而 所有 都可以有一些明显的和更微妙的问题。在寻找提供“同步”解决方案的第三方服务时,您还应该非常小心。通常,这仅包括一个非常基本的功能集。但也许,这对您的应用来说已经足够了。

标签: ios web-services core-data


【解决方案1】:

您遇到了经典的插入/更新/删除范例。

答案是,视情况而定。如果您获得了一大块 json 数据,那么您可以使用 KVC 从该块中提取唯一 ID,并针对您的上下文进行提取以找出已经存在的内容。从那里它是一个简单的数据块循环,根据需要插入和更新。

如果您没有像这样在一个不错的块中获取数据,那么您可能需要对每条记录进行一次提取,以确定它是插入还是更新。这要贵得多,应该避免。建议提前批量抓取。

删除与获取/更新一样昂贵,因为无论如何您都需要获取对象以删除它们,因此您不妨正确处理更新。

更新

是的,有一种从 Core Data 对象构建字典的有效方法。从 Core Data 中获取现有对象数组后,您可以将其转换为字典:

NSArray *array = ...; //Results from Core Data fetch
NSDictionary *objectMap = [NSDictionary dictionaryWithObjects:array forKeys:[array valueForKey:@"identifier"]];

这假设您的核心数据实体中有一个名为identifier 的属性。根据需要更改名称。

使用那一行代码,您现在可以在 NSDictionary 中拥有所有现有对象,然后您可以在遍历 JSON 时对其进行查找。

【讨论】:

  • 我几乎对我的 web 服务进行批处理请求,并且 JSON 数组响应中的每个对象都有一个唯一的 ID。所以我想我可以像你说的那样做循环。但是,有没有一种有效的方法来做到这一点?我能看到的最好方法是循环遍历核心数据结果并使用唯一 id 作为索引构建映射,然后循环遍历 JSON 块并根据需要插入/删除/更新。有什么更好的方法吗?
  • @omegatai 如果你想一想,上面的方法并不能回答什么时候insert、什么时候delete以及什么时候更新,哪个对象,如果不提供同步算法就无法完成,而同步算法又需要本地和远程管理的元信息。因此,只有当您的本地数据是只读并且不允许删除或插入时,这种方法才有效。如果是这种情况,一个简单的方法是清空本地数据库并插入从服务器接收到的所有对象。如果您的对象少于 1000 个,这也很快。
  • 如果网络服务返回所有对象,而不仅仅是更新的对象,您还可以在所有对象上设置删除标志,按照上述方式进行插入和更新,完成后删除所有标记的对象。这样你的数据就可以被读写了。
【解决方案2】:

最简单的做法是将 Json 恢复为正确映射到它的实体。映射后,确定是否已经存在与实体 ID 匹配的对象,如果存在,则获取实体并合并更改。如果没有,请在 Core Data 中创建一个新实体并将 Json 恢复到它。

如果我在客户端与 Evernote 同步,我正在构建一个应用程序。他们在所有对象和服务器级别上保留一个同步更新编号。因此,当我开始同步时,我会检查我的客户端同步更新计数是否小于服务器。如果是这样,我知道我不同步。如果我的 updateCount 为 400 而服务器为 410,我告诉服务器为我提供 updateCount 400 和 410 之间的所有对象。然后我检查我是否已经拥有这些对象并执行我的更新/创建。

每次在服务器上修改对象时,对象的 updateCount 都会随着服务器的增加而增加。

服务器还保留上次更新的时间戳,我也可以检查它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 2012-08-11
    • 2012-04-16
    • 2014-08-22
    相关资源
    最近更新 更多