ios - 客户端 (iOS) 上的核心数据缓存来自服务器策略的数据

标签 ios core-data architecture

我编写了许多与后端通信的 iOS 应用程序。几乎每次,我都使用 HTTP 缓存来缓存查询并将响应数据 (JSON) 解析为 Objective-C 对象。对于这个新项目,我想知道 Core Data 方法是否有意义。

这是我的想法:

iOS 客户端向服务器发出请求,并将对象从 JSON 解析为 CoreData 模型。

每次我需要一个新对象时,我不是直接获取服务器,而是解析 CoreData 以查看是否已经发出该请求。如果该对象存在且未过期,则使用获取的对象。

但是,如果该对象不存在或已过期(此处将应用一些缓存逻辑),我将从服务器获取该对象并相应地更新 CoreData。

我认为拥有这样的架构可以帮助以下方面:
1.避免对后端进行不必要的查询
2. 全面支持离线浏览(你仍然可以使用DataCore的RDBMS进行关系查询)

现在这是我对诸神的问题:

  • 我知道这需要第二次对后端逻辑进行编码(服务器 + CoreData),但这是否有点矫枉过正?
  • 我低估了任何限制?
  • 还有其他想法吗?
  • 最佳答案

    首先,如果您是注册的 iOS 开发者,您应该可以访问 WWDC 2010 Sessions。其中一个 session 涵盖了您正在谈论的一些内容:“ session 117,构建服务器驱动的用户体验”。您应该可以 find it on iTunes .

    REST/JSON/Core Data 的巧妙组合就像一种魅力,如果您计划重用代码,则可以节省大量时间,但需要有关 HTTP 的知识(以及有关 Core Data 的知识,如果您希望您的应用程序运行良好)和安全)。

    所以关键是要了解 REST 和 Core Data。

  • 了解 REST意味着理解 HTTP 方法(GET、POST、PUT、DELETE、...HEAD ?)和响应代码(2xx、3xx、4xx、5xx)和 header (Last-Modified、If-Modified-Since、Etag、... )
  • 理解核心数据意味着知道如何设计你的模型、设置关系、处理耗时的操作(删除、插入、更新),以及如何在后台让事情发生,让你的 UI 保持响应。当然,如何在 sqlite 上进行本地查询(例如,为了预取 id,您可以在获得服务器端等效项后更新对象而不是创建新对象)。

  • 如果您计划为您提到的任务实现可重用的 API,您应该确保您了解 REST 和核心数据,因为这可能是您进行最多编码的地方。 (用于网络层(或任何其他)的现有 API - ASIHttpRequest 和用于解析的任何好的 JSON 库(例如 SBJSON )都可以完成这项工作。

    使这种 API 变得简单的关键是让您的服务器提供 RESTful 服务,并且您的实体持有所需的属性(dateCreated、dateLastModified 等),以便您可以创建请求(使用 ASIHttpRequest 很容易完成,无论是 GET、PUT、 POST, DELETE) 并添加适当的 Http-Headers,例如对于条件 GET:If-Modified-Since。

    如果您已经对 Core Data 感到满意并且可以处理 JSON 并且可以轻松地执行 HTTP 请求和处理响应(同样,ASIHttpRequest 在这里有很大帮助,但还有其他的,或者您可以坚持使用较低级别的 Apple NS-Classes 并执行它自己),那么您只需要为您的请求设置正确的 HTTP header ,并适本地处理 Http-Response-Codes(假设您的服务器是 REST-ful)。

    如果您的主要目标是避免从服务器端等效项重新更新 Core-Data 实体,只需确保您的实体中有一个“last-modified”属性,并对服务器执行有条件的 GET(设置“If-Modified-Since” Http-Header 到您的实体“上次修改”日期。如果该资源没有更改(假设服务器是 REST-ful),服务器将响应状态代码 304(未修改) . 如果更改,服务器会将“Last-Modified” Http-Header 设置为上次更改的日期,将响应 Status-Code 200 并在正文中传递资源(例如,以 JSON 格式)。

    因此,与往常一样,您的问题的答案总是可能“视情况而定”。
    这主要取决于您想在可重用的全能核心数据/休息层中放入什么。

    告诉你数字:我花了 6 个月的时间(在我的业余时间,每周 3-10 小时的速度)让我的位置达到我想要的位置,老实说,我仍在重构,重命名,让它成为现实处理特殊用例(取消请求、回滚等)并提供细粒度的回调(可达性、网络层、序列化、核心数据保存...),.但它非常干净、精致和优化,希望能满足我雇主的一般需求(具有多个 iOS 应用程序的分类广告的在线市场)。那段时间包括学习、测试、优化、调试和不断更改我的 API(首先添加功能,然后改进它,然后从根本上简化它,然后再次调试它)。

    如果上市时间是您的首要任务,那么您最好采用简单实用的方法:不要在意可重用性,只需牢记所学,并在下一个项目中重构,在这里和那里重用和修复代码。最后,所有经验的总和可能会在您的 API 的工作方式及其提供的内容的清晰愿景中具体化。如果您还没有到那里,请继续努力使其成为项目预算的一部分,并尝试重用尽可能多的稳定的 3'rd-Party API。

    抱歉回复太长了,我觉得您正在涉足构建通用 API 甚至框架之类的事情。这些事情需要时间、知识、内务和长期 promise ,而且大多数时候,它们都是浪费时间,因为你永远不会完成它们。

    如果您只想处理特定的缓存场景以允许离线使用您的应用程序并最小化网络流量,那么您当然可以只实现这些功能。只需在您的请求中设置 if-modified-since header ,检查上次修改的 header 或 etag,并将该信息保留在您的持久实体中,以便您可以在以后的请求中重新提交此信息。当然,我也建议使用相同的 HTTP header 在本地缓存(持久)资源,例如图像。

    如果您有能力修改(以 REST-ful 方式)服务器端服务,那么您很好,只要您实现得很好(根据经验,您可以节省多达 3/4 的网络/解析代码iOS 端,如果服务表现良好(返回适当的 HTTP 状态代码,避免检查 nil、字符串、日期的数字转换、提供查找 ID 而不是隐式字符串等......)。

    如果您没有这种奢侈,那么要么该服务至少是 REST-ful(这有很大帮助),要么您必须在客户端解决问题(这通常很痛苦)。

    关于ios - 客户端 (iOS) 上的核心数据缓存来自服务器策略的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4878586/

    相关文章:

    ios - 如何在 Xcode 4.5 中创建 IOS 5.1 应用程序

    ios - 如何使用 Swift 在 iOS 中每 24 小时添加一次变量?

    objective-c - 以父/子关系将数据从工作表传递到 insertNewObject

    java - 部署 Web 服务的好习惯是什么?

    ios - 如何以编程方式从 ios7 设备获取未更改的设备 ID

    ios - 高级服务免费试用期

    Iphone 核心数据在保存时崩溃

    iOS:如何使用整数值对 TableView 进行排序但想要显示字符串值?

    php - 抢先验证还是异常处理?

    java - 限制访问 Java 包