关于ios:如何将iPhone核心数据与Web服务器同步,然后推送到其他设备?

How to Sync iPhone Core Data with web server, and then push to other devices?

我一直在研究一种方法,在多个设备(如iPad或Mac)之间同步存储在iPhone应用程序中的核心数据。在iOS上使用核心数据的同步框架不多(如果有的话)。但是,我一直在思考以下概念:

  • 对本地核心数据存储进行更改,并保存更改。(A)如果设备联机,它将尝试将变更集发送到服务器,包括发送变更集的设备的设备ID。(b)如果变更集未到达服务器,或者设备未联机,应用程序将把变更集添加到队列中,以便在设备联机时发送。
  • 位于云端的服务器将接收到的特定更改集与主数据库合并。
  • 在云服务器上合并变更集(或变更集队列)后,服务器将所有这些变更集推送到使用某种轮询系统向服务器注册的其他设备。(我本来想使用苹果的推送服务,但根据评论,这显然不是一个可行的系统。)
  • 有什么花哨的事需要我考虑吗?我已经研究了REST框架,如ObjectereSource、核心资源和RestfulCoreData。当然,这些都是使用RubyonRails工作的,我并不依赖于它,但它是一个开始的地方。我对解决方案的主要要求是:

  • 任何更改都应在后台发送,而不应暂停主线程。
  • 它应该使用尽可能少的带宽。
  • 我考虑过一些挑战:

  • 确保服务器上连接了不同设备上不同数据存储的对象ID。也就是说,我将有一个包含对象ID和设备ID的表,通过对存储在数据库中的对象的引用进行绑定。我将有一条记录(databaseid[此表唯一]、objectid[整个数据库中的项目唯一]、datafield1、datafield2),objectid字段将引用另一个表allobjects:(objectid、deviceid、deviceobjectid)。然后,当设备向上推送变更集时,它将从本地数据存储中的核心数据对象传递设备ID和对象ID。然后我的云服务器将对照allobjects表中的objectid和device id进行检查,并在初始表中找到要更改的记录。
  • 所有更改都应该有时间戳,以便合并。
  • 设备将不得不轮询服务器,而不会消耗太多电池。
  • 如果/当从服务器收到更改时,本地设备还需要更新内存中保存的任何内容。
  • 还有什么我不知道的吗?我应该看看什么样的框架才能实现这一点?


    我做了一些和你想做的相似的事情。让我告诉你我学到了什么以及我是如何做到的。

    我假设您的核心数据对象和服务器上的模型(或DB模式)之间有一对一的关系。您只需要保持服务器内容与客户机同步,但客户机也可以修改和添加数据。如果我没弄错,那就继续读下去。

    我添加了四个字段来帮助同步:

  • 同步状态-仅将此字段添加到核心数据模型中。应用程序使用它来确定您是否对该项目有挂起的更改。我使用以下代码:0表示没有更改,1表示它已排队等待与服务器同步,2表示它是临时对象,可以清除。
  • 已删除-将此添加到服务器和核心数据模型。删除事件不应该实际地从数据库或客户机模型中删除一行,因为它使您没有任何可同步的内容。通过使用这个简单的布尔标记,您可以将"删除"设置为1,同步它,所有人都会很高兴。您还必须修改服务器和客户端上的代码,以查询"is_deleted=0"的未删除项。
  • 上次修改-将此添加到服务器和核心数据模型。每当该记录发生任何更改时,服务器应自动用当前日期和时间更新此字段。它不应该被客户修改。
  • guid-在服务器和核心数据模型中添加一个全局唯一ID(请参阅http://en.wikipedia.org/wiki/globally_unique_identifier)字段。此字段将成为主键,并在客户端上创建新记录时变得重要。通常,您的主键是服务器上一个递增的整数,但我们必须记住,内容可以离线创建,稍后进行同步。guid允许我们在脱机时创建密钥。
  • 在客户机上,添加代码以将模型对象上的同步状态设置为1,无论什么时候发生更改,需要同步到服务器。新模型对象必须生成一个guid。

    同步是一个单独的请求。请求包含:

    • 模型对象的最大上次修改时间戳。这会告诉服务器您只需要在这个时间戳之后进行更改。
    • 包含所有同步状态为1的项的JSON数组。

    服务器获取请求并执行以下操作:

    • 它从JSON数组中获取内容,并修改或添加所包含的记录。最后修改的字段将自动更新。
    • 服务器返回一个JSON数组,其中包含最后修改时间戳大于请求中发送的时间戳的所有对象。这将包括它刚接收到的对象,这些对象用于确认记录已成功同步到服务器。

    应用程序接收响应并执行以下操作:

    • 它从JSON数组中获取内容,并修改或添加所包含的记录。每个记录的同步状态设置为0。

    希望有帮助。我把单词record和model交替使用,但我想你明白了。祝你好运。


    我建议仔细阅读和执行DanGrover在iPhone2009大会上讨论的同步策略,这里提供一个PDF文档。

    这是一个可行的解决方案,并不难实现(Dan在其几个应用程序中实现了这一点),与Chris描述的解决方案重叠。有关同步的深入理论讨论,请参阅Russ Cox(麻省理工学院)和William Josephson(普林斯顿)的论文:

    矢量时间对文件同步

    这同样适用于核心数据,但有一些明显的修改。这提供了一个整体上更强大和可靠的同步策略,但需要更多的努力才能正确地实现。

    编辑:

    格罗弗的PDF文件似乎不再可用(断开链接,2015年3月)。更新:链接可通过此处的返回机器获得。

    考虑到iCloud最终似乎支持正确的核心数据同步,MarcusZarra开发的名为zsync的Objective-C框架已经被弃用。


    如果你还在寻找出路,那就看看CouchBase手机。这基本上就是你想要的。(http://www.couchbase.com/nosql-databases/couchbase-mobile)


    类似于@cris,我已经实现了客户机和服务器之间的同步类,并解决了迄今为止所有已知的问题(向服务器发送/接收数据、基于时间戳合并冲突、删除不可靠网络条件下的重复项、同步嵌套数据和文件等)。

    您只需告诉类它应该同步哪个实体和哪些列,以及您的服务器在哪里。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    M3Synchronization * syncEntity = [[M3Synchronization alloc] initForClass: @"Car"
                                                                  andContext: context
                                                                andServerUrl: kWebsiteUrl
                                                 andServerReceiverScriptName: kServerReceiverScript
                                                  andServerFetcherScriptName: kServerFetcherScript
                                                        ansSyncedTableFields:@[@"licenceNumber", @"manufacturer", @"model"]
                                                        andUniqueTableFields:@[@"licenceNumber"]];


    syncEntity.delegate = self; // delegate should implement onComplete and onError methods
    syncEntity.additionalPostParamsDictionary = ... // add some POST params to authenticate current user

    [syncEntity sync];

    您可以在这里找到源代码、工作示例和更多说明:github.com/knagode/m3synchronization。


    我认为解决guid问题的一个好办法是"分布式ID系统"。我不确定正确的术语是什么,但我认为这是MS SQL Server文档用来调用它的(SQL对分布式/同步数据库使用/使用此方法)。很简单:

    服务器分配所有ID。每次同步完成后,首先检查的是"这个客户机上还剩下多少个ID?"如果客户机的运行速度很低,它会向服务器请求一个新的ID块。然后,客户机将该范围内的ID用于新记录。这对于大多数需求都很有用,如果您可以分配一个足够大的块,使它在下次同步之前"永远"不会用完,但不能太大,以致服务器会随着时间的推移而用完。如果客户机确实用完了,那么处理就非常简单,只需告诉用户"抱歉,在同步之前不能添加更多项目"…如果他们添加了那么多的项目,那么他们不应该同步以避免过时的数据问题吗?

    我认为这比使用随机guid要好,因为随机guid不是100%安全的,而且通常需要比标准ID(128位对32位)长得多。通常按ID建立索引,并将ID号保存在内存中,因此保持其较小很重要。

    我不想把它作为答案发表,但我不知道有人会把它当作评论,我认为它对这个主题很重要,不包括在其他答案中。


    我刚刚发布了我的新核心数据云同步API的第一个版本,称为同步云。同步云与iCloud有很多不同之处,因为它允许多用户同步界面。它也不同于其他同步API,因为它允许多表关系数据。

    请访问http://www.syncloudapi.com了解更多信息。

    使用iOS 6 SDK构建,从2012年9月27日起是最新的。


    注意用户通过推送通知更新数据。使用应用程序中的后台线程检查本地数据和云服务器上的数据,当服务器上发生更改时,更改本地数据,反之亦然。

    因此,我认为最困难的部分是估计哪些方面是无效的数据。

    希望这能帮助你


    首先,您应该重新考虑您将拥有多少数据、表和关系。在我的解决方案中,我通过Dropbox文件实现了同步。我观察主MOC中的更改,并将这些数据保存到文件中(每行保存为gzip JSON)。如果有Internet连接工作,我会检查Dropbox上是否有任何更改(Dropbox会给我增量更改),下载并合并(最新的胜利),最后放入更改的文件。在同步之前,我将锁定文件放在Dropbox上,以防止其他客户端同步不完整的数据。下载更改时,只下载部分数据是安全的(例如,失去互联网连接)。当下载完成(全部或部分)时,它开始将文件加载到核心数据中。当存在未解决的关系(并非所有文件都已下载)时,它将停止加载文件并稍后尝试完成下载。关系仅存储为guid,因此我可以轻松检查要加载的文件是否具有完整的数据完整性。对核心数据进行更改后,开始同步。如果没有更改,则每隔几分钟检查Dropbox和应用程序启动时的更改。另外,当更改被发送到服务器时,我会向其他设备发送一个广播,通知它们有关更改的信息,这样它们就可以更快地同步。每个同步实体都有guid属性(guid也用作Exchange文件的文件名)。我也有同步数据库,我在其中存储每个文件的Dropbox修订版(我可以在Dropbox Delta重置其状态时对其进行比较)。文件还包含实体名、状态(已删除/未删除)、GUID(与文件名相同)、数据库修订(用于检测数据迁移或避免与Never-App版本同步)以及数据(如果未删除行)。

    此解决方案适用于数千个文件和大约30个实体。我可以使用key/value store代替Dropbox作为REST Web服务,我想稍后再做,但没有时间这样做:)目前,在我看来,我的解决方案比iCloud更可靠,这非常重要,我完全控制了它的工作方式(主要是因为它是我自己的代码)。

    另一种解决方案是将MOC更改保存为事务处理——与服务器交换的文件将少得多,但很难按照正确的顺序将初始负载加载到空的核心数据中。iCloud就是这样工作的,其他同步解决方案也有类似的方法,例如TicoredataSync。

    ——更新

    过了一会儿,我迁移到了Ensembles——我推荐这个解决方案,而不是重新设计轮子。


    2017年

    对于这incredibly老问题。P></

    我非常喜欢问恩好P></

    "I want to buy a device which is a phone that I can carry with me - but also use for many computing tasks, even browsing the WWW!"

    一个明显的答案to that is,the如果你是火星人在线,在线技术realized of the main这个星球recently是"智能电话",购买一个。P></

    这些天,creating安OCC系统校正的划痕从摇篮as as an creating SQL数据库从划痕。P></

    OCC明显,for which is the范式基础,现在应用的非平凡的学院,你使用P></

    • firebase
    • pubnub
    • couchbase

    和我在线,which are那么简单,这个专业的人几年科技of the last。P></

    今日,你会创造,没有更多的比你能从划痕OCCP></

    • 写你自己的操作系统从划痕P></

    • 写你自己的SQL数据库从划痕P></

    • 写你自己的字体渲染从划痕P></

    在已知的,真的,我不能在你的专业感""安安还Android程序员程序员"或"任何更多。P></

    谁在乎knowing about how to布局表和按钮?P></

    无论你在firebase /专家安端的问题,当你知道如何'按钮的布局,还在线或Android等。P></

    唯一的问题是使用for example to which先生,也许playfab if it is…pubnub游戏对象,如果它是真的ably.io消息驱动,也许,也许,如果你kinvey任何公司。P></