嘿,我正在为我们的应用程序创建模型层。
一些要求是这样的:
- 它应该可以在 iPhone OS 3.0+ 上运行。
- 我们的数据来源是一个 RESTful Rails 应用程序。
- 我们应该使用 Core Data 在本地缓存数据。
- 客户端代码(我们的 UI Controller )应该尽可能少地了解任何网络内容,并且应该使用 Core Data API 查询/更新模型。
我查看了关于构建服务器驱动的用户体验的 WWDC10 Session 117,花了一些时间查看了 Objective Resource , Core Resource , 和 RestfulCoreData构架。
Objective Resource 框架本身并不与 Core Data 对话,它只是一个 REST 客户端实现。 Core Resource 和 RestfulCoreData 都假设您在代码中与 Core Data 对话,它们解决了模型层背景中的所有具体细节。
到目前为止,一切看起来都还不错,虽然最初我认为 Core Resource 或 RestfulCoreData 都可以满足上述所有要求,但是......有几件事似乎都没有正确解决:
- 将本地更新保存到服务器时不应阻塞主线程。
- 如果保存操作失败,则应将错误传播到 UI,并且不应将任何更改保存到本地 Core Data 存储。
当您在托管对象上下文上调用 - (BOOL)save:(NSError **)error
时,Core Resource 恰好向服务器发出所有请求,因此能够提供正确的对服务器的底层请求的 NSError 实例以某种方式失败。但它会阻塞调用线程,直到保存操作完成。失败。
RestfulCoreData 保持您的 -save:
调用完好无损,并且不会为客户端线程引入任何额外的等待时间。它只是监视 NSManagedObjectContextDidSaveNotification
,然后在通知处理程序中向服务器发出相应的请求。但是这样 -save:
调用总是成功完成(好吧,鉴于Core Data对保存的更改没问题)并且实际调用它的客户端代码无法知道保存可能失败由于某些 404
或 421
或发生任何服务器端错误而传播到服务器。更重要的是,本地存储会更新数据,但服务器永远不知道这些变化。失败。
所以,我正在寻找一种可能的解决方案/常见做法来处理所有这些问题:
- 我不希望调用线程在网络请求发生时阻塞每个
-save:
调用。 - 我想以某种方式在 UI 中收到一些同步操作出错的通知。
- 如果服务器请求失败,我希望实际的 Core Data 保存也失败。
有什么想法吗?
最佳答案
对于这个用例,您真的应该看看 RestKit (http://restkit.org)。它旨在解决建模和同步远程 JSON 资源到本地 Core Data 支持的缓存的问题。它支持离线模式,在没有可用网络时完全从缓存中工作。所有同步都发生在后台线程(网络访问、负载解析和托管对象上下文合并)上,并且有一组丰富的委托(delegate)方法,因此您可以了解发生了什么。
关于iphone - 如何异步同步 CoreData 和 REST Web 服务,同时正确地将任何 REST 错误传播到 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3077444/