【问题标题】:Keeping Core Data Objects in multiple stores将核心数据对象保存在多个商店中
【发布时间】:2014-05-14 19:14:50
【问题描述】:

我正在使用 Core Data 开发一个 iOS 应用程序。我想让持久存储位于共享位置,例如网络驱动器,以便多个用户可以处理数据(在不同的时间,即并发不是问题的一部分)。

但我还想提供“离线”处理数据的能力,即通过在 iPad 上保留本地持久存储。到目前为止,我读到我可以通过使用持久存储协调器的迁移功能在某种程度上做到这一点,但这似乎意味着旧存储随后失效。此外,我不一定要移动整个商店“离线”,而只是移动其中的一部分:使用 Apple 提供的简单“公司部门”示例,我希望用户能够检查一个部门,同时与该部门关联的所有员工(以及与每个员工关联的所有属性)。然后,用户可以在他们的 iPad 上本地处理部门数据,并在一段时间后将这些更改同步回服务器的持久存储。

所以,我需要将核心数据对象从一个存储复制到另一个存储,以及通过关系引用的所有对象。并且这个复制过程还需要确保如果目标持久存储中已经存在一个对象,它会被覆盖而不是添加到存储中的新对象(我已经为每个对象提供了一个 UID 出于另一个原因,所以我可能能够重复使用 UID)。

从我目前所见,似乎没有简单的方法来同步或复制 Core Data 持久存储,这是一个公平的评估吗?

那么我真的需要编写一段代码来执行以下操作:

  • 通过 MOC 检索对象“A”
  • 在所有实体中检索与对象“A”有关系的所有对象
  • 为目标持久存储实例化一个新的 MOC
  • 对于检索到的每个对象,检查目标存储是否存在该对象
  • 如果对象存在,则使用在步骤 1 和 2 中检索到的对象的属性覆盖它
  • 如果对象不存在,创建它并根据在步骤 1 和 2 中检索到的对象设置所有属性

虽然这不是世界上最复杂的事情,但我仍然认为“在线/离线编辑”的这种要求足够普遍,以至于某些标准功能可用于同步部分持久性存储?

非常感谢您的观点, 谢谢, 大佬

【问题讨论】:

  • 事实上,这是世界上最复杂的事情。

标签: ios core-data synchronization nspersistentstore


【解决方案1】:

我对上面的评论只是半开玩笑。您确实在描述一个非常困难的问题 - 很难确定这种同步,而且在任何开发环境中,很少有会成为“正常工作”的交钥匙解决方案。我认为您上面的伪代码描述非常准确地描述了您需要做什么。尽管可以概括一些遍历关系和检查现有对象的工作,但您谈论的是一些潜在复杂的异常处理情况 - 例如,如果更新一个对象,并且只有 5 个相关对象中的 1 个在某种程度上已过时,您是丢弃更新还是应用部分更新?您说“并发”不是问题的一部分,但是如果多个用户可以同时“签出”对象,除非您计划对这些对象设置锁定机制,否则您在尝试进行更新时会开始发生冲突。

需要检查的是 Core Data 中用于利用 iCloud 的新功能 - 我怀疑这会帮助解决您的问题,但它通常是相关的。

由于您想与您的数据一起在网络上运行,另一件需要考虑的事情是 Core Data 是否适合您的一般问题。由于 Core Data 在很大程度上是一种旨在支持 UI 和 MVC 模式的技术,如果您的数据需求不是特别绑定到 UI,您可能会考虑另一种类型的 DB 解决方案。

如果您实际上以超越建模的重要方式利用 Core Data,在驱动您的 UI 方面,并且您想坚持使用它,我认为您的分析是正确的:您将不得不滚动您自己的解决方案。我认为构建和测试将是一件不平凡的事情。

要考虑的一个选项是 CouchDB 和一个称为 TouchDB 的 iOS 实现。这意味着对您的问题采用更多面向文档 (JSON) 的方法,根据您的描述,这实际上可能是合适的。

【讨论】:

  • 您好 Rob,感谢您的回复。所以它真的必须手动完成。呃。不过,并发性应该不是问题——我可以向部门实体添加一个“签出”属性。所有员工等只能分配到一个部门,所以只要我对签入和签出的能力应用一些逻辑,我应该会很好。我会检查一下 TouchDB,也许这确实是一个更好的方法,但我确实喜欢 Core Data 的功能,而且我必须处理大型集合,即数千名员工,我希望最大限度地减少实际加载到的数据量应用程序。
  • 一旦您在 Core Data 中设置了基本模型,通过在模型中填充数千个对象来运行一些性能测试,并确认您可以获得所需的性能,这将是值得的.根据您运行它的设备的功能以及 SQLite 后端所需查询的复杂性,您可能会遇到性能问题。 Core Data 不是数据库,这在数千个对象中变得很明显。我非常喜欢 Core Data - 它解决了很多问题,但无法扩展。
【解决方案2】:

就我目前所见,我认为最好的方法是RestKit。它提供了一个核心数据包装器,它使用 JSON 在远程和本地存储之间移动数据。我还没有完全尝试过,但从文档中的内容来看,它听起来非常强大,非常适合我的需求。

【讨论】:

  • 嗯。更深入地研究 RestKit,我发现了两件事:它的源代码经常更改,以至于一些关于 RestKit 的教程和示例经常不起作用,并且经常包含错误的内容。令人惊讶的是 API 发生了多大的变化……其次 - 它没有做我想要的 - 使用 HTTP 来查询位于远程的 Core Data 持久存储。它允许我使用外部可用的 RESTful Web 服务并将它们存储在 Core Data 中……尽管我并没有真正看到这样做的好处。无论如何,无法获取远程核心数据内容。叹息。
  • 我查看了 RestKit 并得出了与您大致相同的结论 - 而且,我觉得我会让我的模型以没有意义的方式适合 JSON。我现在正在做一个涉及远程对象传输的项目,所以如果你有什么想法,请告诉我。我正在推进一种基于消息的架构,该架构将大部分内容保存在文件中——我很想利用 Core Data,但它并不适合。
  • Hey Rob - 我现在正在尝试的(如果我成功了,我会很乐意分享我的代码,尽管它可能很简单)是使用 WebAppKit(一个非常简单的 HTTP 服务器框架)服务器/MacOS 采用本地核心数据实现并通过 JSON 将其发送到 iOS 设备。显然,已经有足够多的 JSON-to-Core-Data 框架了,所以应该相当简单。
  • WebAppKit 看起来很有希望。我正在使用 CocoaHTTPServer 做类似的事情——我的解决方案仅适用于 iOS,因此 WebAppKit 不是一个选项(看起来它仅适用于 Mac OS)。我也查看了codeworkshop.net/posts/a-routing-cocoahttpserver - 按描述工作 - 但决定在基本 HTTP 之上推出我自己的面向消息的框架。我使用了 HTTP,但我不需要提供 Web 浏览器访问,因此不需要使用 URL 路径来实现我的界面。消息(归档的 NSObject)被传递到根路径,并包含它们自身内部的所有路由/处理信息。
  • 听起来很有趣 - 请让我随时了解您的进度!
【解决方案3】:

你绝对应该检查这些事情:

Parse.com - 基于云的数据存储

PFIncrementalStore https://github.com/sbonami/PFIncrementalStore - NSIncrementalStore 的子类,允许您的 Persistent Store Coordinator 同时在本地和远程(在 Parse Cloud 上)存储数据

所有这些东西都有据可查。 Parse.com 还将发布 iOS 本地数据存储 SDK http://blog.parse.com/2014/04/30/take-your-app-offline-with-parse-local-datastore/,这将有助于保持数据同步。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-15
    • 2017-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    相关资源
    最近更新 更多