核心数据云同步 – 需要逻辑帮助

我正在为我正在开发的核心数据应用程序集思广益的云同步解决scheme。 我打算一旦完成这个工作,就开放源代码,任何人都可以使用他们的核心数据应用程序,所以从社区input这个系统应该如何工作,非常感谢:-)这是我在想什么:

服务器端


存储提供商

与所有的云同步系统一样,存储是一个难题。 有很多方法来处理这个问题。 我可以build立自己的服务器用于存储,或者使用像Amazon S3这样的服务,但是因为我是以$ 0的资本开始的,所以在这个时候,付费存储解决scheme不是一个可行的select。 经过一番思考,我决定与Dropbox (一个已经很好build立的云同步应用程序和存储提供商)解决。 使用Dropbox的优点是:

  • 它是免费的(对于有限的空间)
  • 除了作为存储服务之外,它还处理云同步
  • 他们最近发布了一个Objective-C SDK,这使得在Mac和iPhone应用程序中使用它更容易

如果我决定在将来转换到不同的存储提供商,我打算在这个云同步框架中添加“服务”,基本上允许任何人创build一个服务类来与他们select的存储提供者连接,这可以简单地插入框架。

存储结构

这是一个非常困难的部分,所以我需要尽可能多的input,我可以在这里。 我一直在想这样的结构:

CloudSyncFramework ======> [app name] ==========> devices =============> (device id) ================> deviceinfo ================> changeset ==========> entities =============> (entity name) ================> (object id) 

这个结构的快速解释:

  • 主“CloudSyncFramework”(名称未定)文件夹将为每个使用该框架的应用程序包含单独的文件夹
  • 每个应用程序文件夹都包含设备文件夹和实体文件夹
  • 设备文件夹将包含为该帐户注册的每个设备的文件夹。 设备文件夹将根据设备ID进行命名,使用[[UIDevice currentDevice] uniqueIdentifier] (在iOS上)或序列号(在Mac OS上)等获得。
  • 每个设备文件夹包含两个文件: deviceinfochangesetdeviceinfo包含有关设备的信息(例如操作系统版本,上次同步date,型号等),并且更改集文件包含有关自设备上次同步后发生更改的对象的信息。 这两个文件将只是简单的NSDictionaries使用NSKeyedArchiver归档到文件。
  • 每个核心数据实体在实体文件夹下都有一个子文件夹
  • 在每个实体文件夹下,属于该实体的每个对象将具有单独的文件。 这个文件将包含一个带有键值对的JSON字典。

同步同步

这是我几乎完全无能为力的领域之一。 我将如何处理2台设备同时连接和同步云? 这里似乎有很高的风险,甚至数据损坏。

处理迁移

再一次,在这里又一个无知的地方。 我将如何处理核心数据pipe理对象模型的迁移? 在这里最简单的做法似乎只是擦拭云数据存储清理,并从经过迁移过程的设备上传数据的新副本,但这似乎有些风险,并且可能有更好的方法。

客户端


将NSManagedObjects转换为JSON

将属性转换为JSON不是一件非常困难的任务(在Web上浮动的代码很多)。 关系是这里的关键问题。 在这个 stackoverflow后,Marcus Zarra张贴关系对象本身被添加到JSON字典的代码。 但是,他提到这可能会导致无限循环取决于模型的结构,而且我不确定这是否适用于我的方法,因为我将每个对象存储为单个文件。

我一直在试图find一个方法来获得一个NSManagedObject的string的ID。 然后,我可以将关系保存为JSON数组。 我发现的最接近的是[[managedObject objectID] URIRepresentation] ,但是这不是一个对象的ID,它更像是持久化存储中对象的位置,我不知道它的具体[[managedObject objectID] URIRepresentation]是否足够用作对象的参考。

我想我可以为每个对象生成一个UUIDstring,并将其保存为一个属性,但我打开的build议。

将更改同步到云中

第一个(也是最好的)解决scheme就是听取NSManagedObjectContextObjectsDidChangeNotification获取已更改对象的列表,然后更新/删除/插入云数据存储中的这些对象。 更改保存后,我需要更新每个其他注册设备的变更集文件以反映新更改的对象。

这里出现的一个问题是, 我将如何处理失败或中断的同步? 。 我的一个想法是首先将更改推送到云中的临时目录,然后一旦确认成功,将其与云上的主数据合并,以使同步中间的中断不会损坏数据。 然后,我会将需要在云中更新的对象的logging保存到plist文件中,以便在下次连接到互联网时推送。

检索更改的对象

这很简单,设备下载它的变更文件,计算出哪些对象需要更新/插入/删除,然后相应地执行。

这总结了我对这个系统将使用的逻辑的想法:-)任何洞察力,build议,问题的答案等, 非常感谢。

UPDATE

经过大量的思考和阅读TechZens的build议,我对概念做了一些修改。

我想到的最大的变化就是让每个设备都有一个单独的数据存储在云中。 基本上,每次pipe理的对象上下文保存 (感谢TechZen),它会将更改上传到该设备的数据存储。 更新这些更改后,将创build一个包含更改详细信息的“更改集”文件,并将其保存到正在使用该应用程序的OTHER设备的更改集文件夹中。 当其他设备连接到同步时,他们将通过变更集文件夹并将每个变更集应用到本地数据存储,然后在云中更新其各自的数据存储。

现在,如果一个新设备注册到该帐户,它将从所有设备中find最新的数据副本,并将其下载以用作其本地存储。 这解决了同时同步的问题,并减less了数据损坏的可能性,因为没有“中央”数据存储,每个设备仅接触其数据并且仅更新改变,而不是每个设备同时访问和修改相同的数据。

有一些明显的冲突情况需要处理,主要是删除对象。 如果正在下载更改集,指示应用程序删除当前正在编辑的对象等,则需要有方法来处理此问题。

你想看看这个悲观的云同步: 为什么云同步将永远不会工作。 它涵盖了很多你正在摔跤的问题。 他们中的许多人很难处理。

信息同步是非常非常非常困难的。 添加不同的设备,不同的操作系统,不同的数据结构等往往造成致命的复杂性。 自70年代以来,人们一直在研究这个问题的变种,事情真的没有太大的改进。

根本的问题是,如果让系统变得灵活和可定制,那么同步所有变体的复杂性就会以定制数量的函数呈指数级增长。 如果你使它僵化,你可以同步,但你可以同步的限制。

我将如何处理2台设备同时连接和同步云?

如果你知道,你会变得富有。 对于当前的云同步提供商来说,这是一个大问题。 他们真正的问题在于你没有“同步”你的合并。 软件在合并时很糟糕,因为很难build立一个预定义的规则集来描述所有可能的合并。

最简单的系统是build立规范设备或设备层次结构,以便系统总是知道要select哪个input。 然而,这破坏了灵活性。

我将如何处理核心数据pipe理对象模型的迁移?

核心数据模型的迁移在很大程度上与服务器无关。 这是Core Data自己pipe理的内容。 模型迁移更新模型,即实体图,而不是实际的数据。

将NSManagedObjects转换为JSON

build模关系很难,特别是那些不像Core Data那样容易支持的工具。 但是,永久性pipe理对象ID的URI应该作为UUID,将对象指向特定设备上特定存储区中的特定位置。 在技​​术上没有保证是普遍独特的,但它足够接近所有的实际目的。

将更改同步到云中

我认为你是在混淆核心数据的实施细节与云本身。 如果使用NSManagedObjectContextObjectsDidChangeNotification ,则每当观察到的上下文发生更改时,都会引发networkingstream量,而不pipe这些更改是否被保留。 根据应用程序,这可能会在几分钟内连接数千次。 相反,您只想在最多保存上下文时进行同步。

这里出现的一个问题是,我将如何处理失败或中断的同步?

在同步完成之前,您不会提交更改。 这是一个大问题,并导致数据损坏。 再次,您可以具有灵活性,复杂性和脆弱性,不灵活性,简单性和健壮性。

检索已更改的对象:这非常简单,设备下载其更改集文件,计算出哪些对象需要更新/插入/删除,然后相应地执行

如果你有一个不灵活的数据结构,这只是简单的。 描述一个灵活的数据结构的变化是一场噩梦。

不知道我是否有帮助。 没有一个问题有优雅的解决scheme。 大多数devise师最终都会遇到僵化和/或缓慢的powershell迭代合并。

认真看看RestKit

这是一个开源项目,旨在帮助将iOS应用程序与云数据集成,包括但不限于在客户端上存在该数据的核心数据模型的情况。

我最近开始在我的一个项目中使用它,并发现它非常有用。 在核心数据场景中,您可以实现数据模型和从服务器获取和发布到服务器的内容之间的声明性映射,并且负责将对象从云中注入到客户端模型中,将新对象发布到服务器并将服务器生成的对象ID合并到客户端模型中,在后台线程中完成所有这些操作,并处理所有核心数据上下文线程问题等等。

RestKit绝不是一个成熟的产品,但是有一个相当不错的基础,还有一些可以使用其他贡献者的帮助的东西。 特别是,如果你的目标是创build一个开源的解决scheme,那么贡献和改进这样的东西,而不是重新发明一个新的解决scheme将是非常好的。 当然,除非你看到你的想法和其他现有的解决scheme之间的严重分歧:-)

由于这篇文章是最新的,有几个新的选项可用。 有可能开发一个解决scheme,并有这些解决scheme的运输应用程序。

以下是主要核心数据同步选项的简短列表:

  1. 苹果的原生Core Data / iCloud同步。 (有一个开始,现在看起来好多了。)
  2. TICDS
  3. Wasabi Sync ,付费服务。
  4. Simperium (似乎被遗弃了)
  5. ParcelKit与Dropbox Datastore API
  6. 合奏 ,最近的。 (披露:我是该项目的创始人)

这就像苹果公司回应我的问题,宣布iCloud软件开发工具包 ,与完整的核心数据集成。 赢得!