已关闭。此问题需要超过focused。当前不接受答案。
**想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。
5年前关闭。
Improve this question
我一直在研究一种方法,可以在多台设备(如iPad或Mac)之间同步存储在iPhone应用程序中的核心数据。在iOS上,用于Core Data的同步框架并不多(如果有的话)。不过,我一直在思考以下概念:
1.对本地核心数据存储进行更改,并保存更改。(a)如果设备在线,它会尝试将更改集发送到服务器,包括发送更改集的设备的设备ID。(B)如果更改集未到达服务器,或者如果设备未在线,应用会将更改集添加到队列中,以便在设备在线时发送。
1.位于云中的服务器将接收到的特定更改集与其主数据库合并。
1.当一个变更集(或者变更集队列)在云服务器上合并后,服务器会使用某种轮询系统将所有这些变更集推送到在服务器上注册的其他设备上(我想使用苹果的Push服务,但根据评论,这显然不是一个可行的系统)。
有什么需要我考虑的吗?我已经看过ObjectiveResource、Core Resource和RestfulCoreData等REST框架。当然,这些框架都是使用Ruby on Rails的,我并不依赖于Ruby on Rails,但它是一个起点。我对解决方案的主要要求是:
1.任何更改都应该在后台发送,而不暂停主线程。
1.它应该使用尽可能少的带宽。
我思考了一些挑战:
1.确保在服务器上附加了不同设备上的不同数据存储的对象ID。也就是说,我将有一个对象ID和设备ID的表,它们通过对存储在数据库中的对象的引用联系在一起。(DatabaseId [对此表唯一]、ObjectId [对整个数据库中的项唯一]、Datafield 1、Datafield 2),则ObjectId字段将引用另一个表AllObjects:(ObjectId,DeviceId,DeviceObjectId)。然后,当设备上推更改集时,它将从本地数据存储中的核心数据对象沿着设备Id和objectId。然后,我的云服务器将检查AllObjects表中的objectId和设备Id,并在初始表中找到要更改的记录。
1.所有更改都应加上时间戳,以便合并。
1.该设备将不得不轮询服务器,而不会耗尽太多的电池。
1.如果/当从服务器接收到更改时,本地设备还需要更新存储器中保存的任何内容。
这里我还遗漏了什么吗?我应该看什么样的框架才能使这成为可能?
8条答案
按热度按时间8yparm6h1#
我已经做了一些和你想做的相似的事情,让我告诉你我学到了什么,我是怎么做到的。
我假设您的Core Data对象和服务器上的模型(或数据库架构)之间存在一对一的关系,您只想保持服务器内容与客户端同步,但客户端也可以修改和添加数据,如果我理解正确,请继续阅读。
我添加了四个字段来帮助同步:
1.sync_status-仅将此字段添加到您的核心数据模型中。应用程序使用此字段来确定您是否有挂起的项目更改。我使用以下代码:0表示没有更改,1表示它正在排队等待与服务器同步,2表示它是临时对象,可以清除。
1.is_deleted-将其添加到服务器和核心数据模型中。删除事件不应该实际从数据库或客户端模型中删除一行,因为它没有留下任何东西可以同步。通过使用这个简单的布尔标记,您可以将is_deleted设置为1,同步它,而且每个人都会很高兴。你还必须修改服务器和客户端上的代码,用“is_deleted=0”查询未删除的项目。
1.last_modified-将此字段添加到服务器和核心数据模型中。每当该记录发生任何更改时,服务器应使用当前日期和时间自动更新此字段。客户端决不能修改此字段。
1.guid-添加全局唯一ID(请参阅http://en.wikipedia.org/wiki/Globally_unique_identifier)字段添加到服务器和核心数据模型。此字段将成为主键,并且在客户端上创建新记录时变得很重要。通常,主键在服务器上是一个递增整数,但我们必须记住,内容可以离线创建,稍后再同步。2 GUID允许我们在离线时创建密钥。
在客户端上,添加代码以在发生更改并需要与服务器同步时将模型对象上的sync_status设置为1。新模型对象必须生成GUID。
同步是单个请求。该请求包含:
服务器获取请求并执行以下操作:
应用接收响应并执行以下操作:
我交替使用了唱片和模特这个词,但我想你明白我的意思了。
a7qyws3x2#
我建议仔细阅读并实施Dan Grover在iPhone2009大会上讨论的同步策略,该策略以pdf文档的形式提供。
这是一个可行的解决方案,实现起来并不困难(Dan在它的几个应用程序中实现了这一点),与Chris描述的解决方案重叠。关于同步的深入理论讨论,请参阅Russ Cox(麻省理工学院)和William Josephson(普林斯顿大学)的论文:
File Synchronization with Vector Time Pairs
这同样适用于经过一些明显修改的核心数据。这提供了一个整体上更健壮和可靠的同步策略,但需要更多的努力才能正确实现。
编辑:
似乎格罗弗的pdf文件不再可用(链接断开,2015年3月)。更新:通过Way Back机器here可获得该链接
Marcus Zarra开发的Objective-C框架ZSync已经被弃用,因为iCloud似乎终于支持正确的核心数据同步。
2eafrhcq3#
如果你还在寻找一条路要走,看看CouchBase移动的。这基本上可以满足你的所有需求。(http://www.couchbase.com/nosql-databases/couchbase-mobile)
ha5z0ras4#
类似于@Cris,我实现了客户端和服务器之间的同步类,并解决了目前为止所有已知的问题(向/从服务器发送/接收数据,基于时间戳合并冲突,在不可靠的网络条件下删除重复条目,同步嵌套数据和文件等)。
您只需告诉类应该同步哪个实体和哪些列,以及您的服务器在哪里。
您可以在此处找到源代码、工作示例和更多说明:github.com/knagode/M3Synchronization.
fdbelqdn5#
通过推送通知通知用户更新数据,在应用中使用后台线程检查本地数据和云服务器上的数据,当服务器发生变化时,更改本地数据,反之亦然。
所以我认为最困难的部分是估计哪一方的数据是无效的。
希望这对我们有帮助
brgchamk6#
我刚刚发布了我的新的核心数据云同步API的第一个版本,被称为SyncCloud。SyncCloud与iCloud有很多不同之处,因为它允许多用户同步接口。它也不同于其他同步API的,因为它允许多表,关系数据。
请访问http://www.syncloudapi.com了解更多信息
使用iOS 6 SDK构建,截至2012年9月27日,它是非常最新的。
wtlkbnrh7#
我认为解决GUID问题的一个好方法是“分布式ID系统”。我不知道正确的术语是什么,但我认为这是MS SQL Server文档用来称呼它的(SQL使用/使用这种方法来处理分布式/同步数据库)。
服务器分配所有ID。每次同步完成时,首先检查的是“我在此客户端上还剩下多少ID?”如果客户端运行不足,它会向服务器请求新的ID块。然后客户端将该范围内的ID用于新记录。如果您可以分配足够大的块,使其在下次同步之前“永远不会”用完,则这对大多数需求都很有效。但不能太大以至于服务器会随着时间的推移而耗尽。如果客户端确实耗尽了,处理可以非常简单,只需告诉用户“对不起,在同步之前,您无法添加更多项目”...如果他们添加了那么多项目,他们不应该同步以避免陈旧数据问题吗?
我认为这上级使用随机GUID,因为随机GUID不是100%安全的,并且通常需要比标准ID长得多(128位对32位)。您通常具有按ID的索引,并且经常将ID号保存在内存中,因此保持ID号较小很重要。
我真的不想作为答案发表,但我不知道任何人会看到作为一个评论,我认为这是很重要的这个主题,不包括在其他答案。
92vpleto8#
首先,你应该重新考虑一下你将拥有多少数据、表格和关系。在我的解决方案中,我通过Dropbox文件实现了同步。我观察主MOC中的变化,并将这些数据保存到文件中(每一行都保存为gzipped json).如果有互联网连接工作,我会检查Dropbox上是否有任何变化(Dropbox会提供增量更改),下载并合并(最新获奖),最后放上修改过的文件,同步前我在Dropbox上加了锁定文件,防止其他客户端同步不完整的数据,下载修改时只下载部分数据比较安全(例如失去互联网连接)。下载完成时(全部或部分)它开始加载文件到核心数据。当有未解决的关系(不是所有的文件都被下载)它停止加载文件并尝试稍后完成下载。关系只存储为GUID,这样我就可以轻松地检查要加载哪些文件才能保持完整的数据完整性。同步是在对核心数据进行更改后开始的。如果没有更改,比它每隔几分钟和应用程序启动时检查Dropbox上的更改更多。此外,当更改发送到服务器时,我会向其他设备发送广播,通知他们更改,以便它们可以更快地同步。每个同步实体都有GUID属性(guid也被用作交换文件的文件名)。我也有同步数据库,我在那里存储每个文件的Dropbox版本(我可以在Dropbox delta重置其状态时进行比较).文件还包含实体名称、状态(已删除/未删除)、GUID(与文件名相同)、数据库版本(用于检测数据迁移或避免与从不使用的应用版本同步),当然还有数据(如果行未删除)。
这个解决方案适用于数千个文件和大约30个实体。我可以使用key/value store作为REST网络服务,而不是Dropbox,我想稍后再做,但没有时间:)目前,在我看来,我的解决方案比iCloud更可靠,而且非常重要的是,我可以完全控制它的工作方式(主要是因为它是我自己的代码)。
另一种解决方案是将MOC更改保存为事务-与服务器交换的文件会少得多,但很难按照正确的顺序将初始加载到空的核心数据中。iCloud就是这样工作的,其他同步解决方案也有类似的方法,例如TICoreDataSync。
--更新
过了一段时间,我迁移到Ensembles-我推荐这个解决方案,而不是重新发明轮子。