客户端 (iOS) 上的核心数据缓存来自服务器策略的数据 [英] Core Data on client (iOS) to cache data from a server Strategy

查看:15
本文介绍了客户端 (iOS) 上的核心数据缓存来自服务器策略的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have written many iOS apps that was communicating with the backend. Almost every time, I used HTTP cache to cache queries and parse the response data (JSON) into objective-C objects. For this new project, I'm wondering if a Core Data approach would make sense.

这是我的想法:

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

The iOS client makes request to the server and parse the objects from JSON to CoreData models.

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

Every time I need a new object, instead of fetching the server directly, I parse CoreData to see if I already made that request. If that object exists and hasn't expired, I use the fetched object.

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

However, if the object doesn't exist or has expired (Some caching logic would be applied here), I would fetch the object from the server and update CoreData accordingly.

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

I think having such an architecture could help with the following: 1. Avoid unnecessary queries to the backend 2. Allow a full support for offline browsing (You can still make relational queries with DataCore's RDBMS)

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

Now here's my question to SO Gods:

  1. 我知道这需要第二次编写后端逻辑(服务器 + CoreData),但这是否太过分了?
  2. 我低估了任何限制吗?
  3. 还有其他想法吗?

推荐答案

首先,如果您是注册的 iOS Dev,您应该可以访问 WWDC 2010 Sessions.其中一个会话涵盖了您正在谈论的一些内容:会话 117,构建服务器驱动的用户体验".您应该可以在 iTunes 上找到它.

First of all, If you're a registered iOS Dev, you should have access to the WWDC 2010 Sessions. One of those sessions covered a bit of what you're talking about: "Session 117, Building a Server-driven User Experience". You should be able to find it on iTunes.

REST/JSON/Core Data 的巧妙组合就像一种魅力,如果您计划重用代码,可以节省大量时间,但需要有关 HTTP 的知识(以及有关 Core Data 的知识,如果您想要您的应用程序)以确保性能良好且安全).

A smart combination of REST / JSON / Core Data works like a charm and is a huge time-saver if you plan to reuse your code, but will require knowledge about HTTP (and knowledge about Core Data, if you want your apps to perform well and safe).

所以关键是要理解 REST 和 Core Data.

So the key is to understand REST and Core Data.

  • 理解 REST 意味着理解 HTTP 方法(GET、POST、PUT、DELETE、...HEAD ?) 和响应代码 (2xx, 3xx, 4xx, 5xx) 和标头 (Last-Modified, If-Modified-Since, Etag, ...)

  • Understanding REST means Understanding HTTP Methods (GET, POST, PUT, DELETE, ...HEAD ?) and Response-Codes (2xx, 3xx, 4xx, 5xx) and Headers (Last-Modified, If-Modified-Since, Etag, ...)

了解核心数据意味着了解如何设计模型、设置关系、处理耗时的操作(删除、插入、更新),以及如何在后台进行操作,以便您的 UI 保持响应.当然,还有如何在 sqlite 上本地查询(例如,为了预取 id,这样您就可以在获得服务器端等效项后更新对象而不是创建新对象).

Understanding Core Data means knowing how to design your Model, setting up relations, handling time-consuming operations (deletes, inserts, updates), and how to make things happen in the background so your UI keeps responsive. And of course how to query locally on sqlite (eg. for prefetching id's so you can update objects instead of create new ones once you get their server-side equivalents).

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

If you plan to implement a reusable API for the tasks you mentioned, you should make sure you understand REST and Core Data, because that's where you will probably do the most coding. (Existing API's - ASIHttpRequest for the network layer (or any other) and any good JSON lib (eg. SBJSON) for parsing will do the job.

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

The key to make such an API simple is to have your server provide a RESTful Service, and your Entities holding the required attributes (dateCreated, dateLastModified, etc.) so you can create Requests (easily done with ASIHttpRequest, be they GET, PUT, POST, DELETE) and add the appropriate Http-Headers, e.g. for a Conditional GET: If-Modified-Since.

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

If you already feel comfortable with Core Data and can handle JSON and can easily do HTTP Request and handle Responses (again, ASIHttpRequest helps a lot here, but there are others, or you can stick to the lower-level Apple NS-Classes and do it yourself), then all you need is to set the correct HTTP Headers for your Requests, and handle the Http-Response-Codes appropriately (assuming your Server is REST-ful).

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

If your primary goal is to avoid to re-update a Core-Data entity from a server-side equivalent, just make sure you have a "last-modified" attribute in your entity, and do a conditional GET to the server (setting the "If-Modified-Since" Http-Header to your entities "last-modified" date. The server will respond with Status-Code 304 (Not-Modified) if that resource didn't change (assuming the server is REST-ful). If it changed, the server will set the "Last-Modified" Http-Header to the date the last change was made, will respond with Status-Code 200 and deliver the resource in the body (eg. in JSON format).

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

So, as always, the answer is to your question is as always probably 'it depends'. It mostly depends what you'd like to put in your reusable do-it-all core-data/rest layer.

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

To tell you numbers: It took me 6 months (in my spare time, at a pace of 3-10 hours per week) to have mine where I wanted it to be, and honestly I'm still refactoring, renaming, to let it handle special use-cases (cancellation of requests, roll-backs etc) and provide fine-grained call-backs (reachability, network-layer, serialization, core data saving...), . But it's pretty clean and elaborate and optimized and hopefully fits my employer's general needs (an online market-place for classifieds with multiple iOS apps). That time included doing learning, testing, optimizing, debugging and constantly changing my API (First adding functionality, then improving it, then radically simplifying it, and debugging it again).

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

If time-to-market is your priority, you're better off with a simple and pragmatic approach: Nevermind reusability, just keep the learnings in mind, and refactor in the next project, reusing and fixing code here and there. In the end, the sum of all experiences might materialize in a clear vision of HOW your API works and WHAT it provides. If you're not there yet, keep your hands of trying to make it part of project budget, and just try to reuse as much of stable 3'rd-Party API's out there.

抱歉回复太长,我觉得您正在涉足构建通用 API 甚至框架之类的事情.这些事情需要时间、知识、内务管理和长期承诺,而且大多数情况下,它们都是浪费时间,因为您永远无法完成它们.

Sorry for the lenghty response, I felt you were stepping into something like building a generic API or even framework. Those things take time, knowledge, housekeeping and long-term commitment, and most of the time, they are a waste of time, because you never finish them.

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

If you just want to handle specific caching scenarios to allow offline usage of your app and minimize network traffic, then you can of course just implement those features. Just set if-modified-since headers in your request, inspect last-modified headers or etags, and keep that info persistent in your persistet entities so you can resubmit this info in later requests. Of course I'd also recommend caching (persistently) resources such as images locally, using the same HTTP headers.

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

If you have the luxury of modifying (in a REST-ful manner) the server-side service, then you're fine, provided you implement it well (from experience, you can save as much as 3/4 of network/parsing code iOS-side if the service behaves well (returns appropriate HTTP status codes, avoids checks for nil, number transformations from strings, dates, provide lookup-id's instead of implicit strings etc...).

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

If you don't have that luxury, then either that service is at least REST-ful (which helps a lot), or you'll have to fix things client-side (which is a pain, often).

这篇关于客户端 (iOS) 上的核心数据缓存来自服务器策略的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆