首页 文章

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

提问于
浏览
284

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

  • 对本地核心数据存储进行更改,并保存更改 . (a)如果设备在线,它会尝试将变更集发送到服务器,包括发送变更集的设备的设备ID . (b)如果变更集未到达服务器,或者设备不在线,则应用程序会将更改集添加到队列中,以便在其联机时发送 .

  • 位于 Cloud 中的服务器将其接收的特定更改集与其主数据库合并 .

  • 在 Cloud 服务器上合并更改集(或更改集队列)后,服务器会使用某种轮询系统将所有这些更改集推送到向服务器注册的其他设备 . (我想使用Apple的推送服务,但显然根据评论,这不是一个可行的系统 . )

我需要考虑什么花哨的东西吗?我查看了REST框架,例如ObjectiveResourceCore ResourceRestfulCoreData . 当然,这些都与Ruby on Rails一起使用,我并不依赖它,但它是一个开始的地方 . 我对我的解决方案的主要要求是:

  • 任何更改都应在后台发送而不会暂停主线程 .

  • 它应该尽可能少地使用带宽 .

我考虑过一些挑战:

  • 确保服务器上附加了不同设备上不同数据存储的对象ID . 也就是说,我将有一个对象ID和设备ID表,它们通过对存储在数据库中的对象的引用来绑定 . 我将有一条记录(DatabaseId [此表是唯一的],ObjectId [整个数据库中的项目唯一],Datafield1,Datafield2),ObjectId字段将引用另一个表AllObjects:(ObjectId,DeviceId,DeviceObjectId) . 然后,当设备推送更改集时,它将从本地数据存储中的核心数据对象传递设备Id和objectId . 然后我的 Cloud 服务器将检查AllObjects表中的objectId和device Id,并在初始表中找到要更改的记录 .

  • 所有更改都应加上时间戳,以便合并它们 .

  • 设备必须轮询服务器,而不会耗尽太多电池 .

  • 如果/从服务器收到更改,本地设备还需要更新内存中保存的任何内容 .

我还缺少什么?我应该考虑哪些框架才能实现这一目标?

9 回答

  • -1

    我刚刚发布了我的新Core Data Cloud Syncing API的第一个版本,称为SynCloud . SynCloud与iCloud有很多不同之处,因为它允许多用户同步界面 . 它也与其他同步api不同,因为它允许多表关系数据 .

    请在http://www.syncloudapi.com了解更多信息

    使用iOS 6 SDK构建,它是截至2012年9月27日的最新版本 .

  • 5

    我建议仔细阅读并实施Dan Grover在iPhone 2009大会上讨论的同步策略,作为pdf文档提供here .

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

    File Synchronization with Vector Time Pairs

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

    编辑:

    似乎Grover的pdf文件不再可用(断开的链接,2015年3月) . 更新:链接可通过返回机器here获得

    由于iCloud最终似乎支持正确的核心数据同步,因此被Marcus Zarra开发并由Marcus Zarra开发的Objective-C框架已被弃用 .

  • 141

    我做了类似于你想做的事情 . 让我告诉你我学到了什么以及我是如何做到的 .

    我假设您的Core Data对象与服务器上的模型(或db模式)之间存在一对一的关系 . 您只想保持服务器内容与客户端同步,但客户端也可以修改和添加数据 . 如果我做对了,那就继续读 .

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

    • sync_status - 仅将此字段添加到核心数据模型 . 它排队等待与服务器同步,2表示它是一个临时对象,可以被清除 .

    • is_deleted - 将其添加到服务器和核心数据模型 . 删除事件实际上不应该从数据库或客户端模型中删除行,因为它不会让您无法同步 . 通过这个简单的布尔标志,你可以将is_deleted设置为1,同步它,每个人都会很开心 . 您还必须修改服务器和客户端上的代码,以使用"is_deleted=0"查询未删除的项目 .

    • last_modified - 将其添加到服务器和核心数据模型 . 该字段应自动更新为当前日期和服务器在该记录发生任何变化时的时间 . 它永远不应该被客户修改 .

    • guid - 将全局唯一ID(请参阅http://en.wikipedia.org/wiki/Globally_unique_identifier)字段添加到服务器和核心数据模型 . 此字段成为主键,在客户端上创建新记录时变得很重要 . 通常,您的主键是服务器上的递增整数,但我们必须记住,内容可以脱机创建并在以后同步 . GUID允许我们在离线时创建密钥 .

    在客户端上,添加代码以在模型对象上将sync_status设置为1,只要有更改并需要与服务器同步 . 新模型对象必须生成GUID .

    同步是单个请求 . 该请求包含:

    • 模型对象的MAX last_modified时间戳 . 这告诉服务器您只想在此时间戳之后进行更改 .

    • 包含sync_status = 1的所有项的JSON数组 .

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

    • 它从JSON数组中获取内容并修改或添加它包含的记录 . last_modified字段会自动更新 .

    • 服务器返回一个JSON数组,其中包含last_modified时间戳大于请求中发送的时间戳的所有对象 . 这将包括刚刚收到的对象,用于确认记录已成功同步到服务器 .

    该应用程序收到响应并执行此操作:

    • 它从JSON数组中获取内容并修改或添加它包含的记录 . 每条记录都设置为sync_status为0 .

    我希望有所帮助 . 我交替使用了记录和模型这个词,但我认为你明白了 . 祝好运 .

  • 11

    如果您仍在寻找方法,请查看Couchbase移动设备 . 这基本上可以满足您的所有需求(http://www.couchbase.com/nosql-databases/couchbase-mobile

  • 5

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

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

    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 .

  • 267

    注意用户通过推送通知更新数据 . 在应用程序中使用后台线程检查本地数据和 Cloud 服务器上的数据,而在服务器上进行更改,更改本地数据,反之亦然 .

    所以我认为最困难的部分是估计哪一方无效的数据 .

    希望这可以帮助你

  • 7

    我认为GUID问题的一个很好的解决方案是“分布式ID系统” . 我不确定正确的术语是什么,但我认为这是MS SQL服务器文档用来调用它的(SQL使用/使用此方法用于分布式/同步数据库) . 这很简单:

    服务器分配所有ID . 每次完成同步时,首先检查的是“我在此客户端上剩下多少个ID?”如果客户端运行不足,则会向服务器请求新的ID块 . 然后,客户端使用该范围内的ID来获取新记录 . 这对于大多数需求都很有用,如果你可以分配一个足够大的块,它应该在下一次同步之前“永不”用完,但不要太大以至于服务器会随着时间的推移而耗尽 . 如果客户端确实耗尽,处理可能非常简单,只需告诉用户“抱歉,在您同步之前无法添加更多项目”...如果他们添加了很多项目,则不应同步以避免陈旧数据问题无论如何?

    我认为这优于使用随机GUID,因为随机GUID不是100%安全的,并且通常需要比标准ID(128位对32位)长得多 . 您通常按ID获取索引,并且通常会将ID号保留在内存中,因此将它们保持在较小的位置非常重要 .

    不是真的想发布答案,但我不知道有人会看到评论,我认为这对于这个主题很重要,不包括在其他答案中 .

  • 5

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

    该解决方案适用于数千个文件和大约30个实体 . 而不是Dropbox我可以使用键/值存储作为REST Web服务,我想稍后做,但没有时间这个:)现在,在我看来,我的解决方案比iCloud更可靠,这是非常重要的,我完全控制它是如何工作的(主要是因为它是我自己的代码) .

    另一个解决方案是将MOC更改保存为事务 - 与服务器交换的文件将会少得多,但是以正确的顺序对空核数据进行初始加载会更加困难 . iCloud正在以这种方式工作,其他同步解决方案也有类似的方法,例如TICoreDataSync .

    • 更新

    过了一会儿,我迁移到Ensembles - 我推荐这个解决方案而不是重新发明轮子 .

  • 2

    2017

    关于这个非常古老的问题 .

    这非常像问

    “我想买一台可随身携带的手机 - 但也可用于许多计算任务,甚至可以浏览WWW!”

    显然,答案是 if you've been on Mars, one of the main technologies realized on this planet recently was "smart phones", buy one.

    目前,从头开始创建OCC系统与从头创建SQL数据库一样疯狂 .

    显然,对于OCC来说,你现在使用的是所有非平凡应用程序的基本范例

    • Firebase

    • PubNub

    • Couchbase

    等等,这是 quite simply, the major advance in human technology of the last few years .

    今天,你不会再从头开始创建OCC了

    • 从头开始编写自己的操作系统

    • 从头开始编写自己的SQL数据库

    • 从头开始编写自己的字体渲染

    请注意,事实上,在专业意义上,你不能再是“ios程序员”或“Android程序员” .

    谁在乎知道如何布置表格和按钮?

    你是Firebase /无论专家,作为一个偶然的问题,你知道如何在ios或android上布局按钮等 .

    唯一的问题是使用BAAS - 例如,如果它是面向游戏的话可能是PlayFab,如果它真的是消息驱动的话可能是PubNub,也许是ably.io,如果你是公司的话可能是kinvey - 无论如何 .

相关问题