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

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

问题描述

我写了与后端通信许多iOS应用。几乎每一次,我用HTTP缓存缓存查询和响应数据(JSON)解析为目标-C的对象。对于这个新的项目,我想知道如果核心数据的方法才有意义。

下面是我想:

的iOS用户端使请求到服务器并解析来自JSON的对象CoreData模型

每当我需要一个新的对象,而不是直接获取服务器,我分析CoreData,看看我是否已经取得该请求。如果该对象存在且尚未过期,我用的是获取的对象。

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

我觉得有这样的结构可以与以下帮助:
1.避免到后端不必要的查询
2.允许离线浏览完整支持(你还是可以使用DataCore的RDBMS关系查询)

现在,这里是我的问题,以SO神:


  1. 我知道这有点要求code后端逻辑第二次(服务器+ CoreData),但是这是矫枉过正?

  2. 的任何限制,我有低估?

  3. 任何其他想法?


解决方案

首先,如果你是一个注册的iOS开发,你应该有机会获得WWDC 2010会话。其中一个会议中讨论了你在谈论什么:会话117,构建一个服务器驱动的用户体验。你应该能够发现它在iTunes上

REST的智能组合/ JSON /核心数据就像一个魅力,是一个巨大的节省时间,如果你打算重用你的code,但将需要约HTTP知识(和知识核心数据,如果想让你的应用表现良好和安全的)。

所以关键是要了解REST和核心数据。


  • 意味着理解HTTP方法(GET,POST,PUT,DELETE。 ..HEAD?)和响应 - codeS(2XX,3XX,4XX,5XX)和接头(的Last-Modified,如果-Modified-Since的,Etag的,...)


  • 了解核心数据意味着知道如何设计你的模型,建立关系,处理耗时的操作(删除,插入,更新),以及如何使事情发生的背景让你的UI响应不断。当然,如何在本地的SQLite查询(如为prefetching ID的,所以你可以更新对象而不是创建新的,一旦你得到他们的服务器端当量)。


如果您计划实现你提到的任务可重复使用的API,你应该确保你了解REST和核心数据,因为这是你可能会做最编码。 (现有的API - ASIHtt prequest ,在网络层(或任何其他)和任何好的JSON的lib (例如: SBJSON )进行解析将做的工作。

要做出这样的API简单,关键是要在您的服务器提供一个RESTful服务,以及您的实体持有所需要的属性(dateCreated会,dateLastModified等),这样你就可以创建请求(与ASIHtt prequest轻松完成,无论是GET,PUT,POST,DELETE),并添加相应的HTTP报头,例如:一个条件GET:如果-Modified-Since的

如果你已经感到舒服核心数据,并能处理JSON,可以很容易做到HTTP请求和再处理响应(,ASIHtt prequest有很大帮助,在这里,但也有其他人,或者你可以坚持到较低苹果级NS-类和自己做),那么你需要的是设置正确的HTTP标题为您的请求,并处理HTTP的响应 - codeS适当(假设你的服务器是REST-FUL)。

如果你的主要目标是避免重新更新从服务器端相当于一个核心 - 数据实体,只要确保你在你的实体的最后一次修改属性,并做了有条件的GET到服务器(设置如果-Modified-Since的宀标头到你的实体最后修改日期。服务器将与状态 - code 304(未修改)响应,如果该资源没有改变(假设服务器是REST-FUL)。如果它改变时,服务器将设置的Last-Modified的Http标头到最后的变化作出之日起,将与状态 - code 200响应,并在体内提供资源(例如,在JSON格式)。

所以,一如既往的答案是你的问题是一如既往可能这取决于。
这主要取决于你希望把你的可重复使用的做它,所有的核心数据/休息层的东西。

要告诉你的数字:我花了6个月(在我的业余时间,以每周3-10小时的速度),以有我,我希望它是,老老实实我还在重构,重命名,让它处理特殊用例(请求取消,滚背部等),并提供细粒度的回调(可达性,网络层,系列化,核心数据保存...)。但它是pretty干净和精心优化,并希望符合我的雇主的一般需求(一个在线市场的地方分类与多个iOS应用)。那一次收录在做学习,测试,优化,调试和不断改变我的API(首先添加功能,然后改进它,那么从根本上简化它,然后再次调试它)。

如果时间到市场是你的优先级,你是用一个简单的和务实的态度更好:没关系的可重用性,只要记住所学的知识,并重构中的下一个项目,重复使用和固定这里code和那里。最后,所有经验的总和可能会在如何您的API可行,什么它提供了一个清晰的愿景实现。如果你现在还没有,让你的双手试图让IT项目预算的一部分,只是尝试重用尽可能多的稳定3'rd党的API在那里的。

很抱歉的lenghty反应,我觉得你步入像建立一个通用的API,甚至框架。这些事情需要时间,知识,家政服务和长期的承诺,大部分时间,他们是在浪费时间,因为你永远不完成他们。

如果您只想处理特定的缓存方案,让您的应用程序脱机使用,并最大限度地减少网络流量,那么你当然可以只实现这些功能。只是如果 - 修改 - 因为你的请求头,检查最后修改页眉或ETag的,并保持了持续的信息在你的persistet实体,因此您可以重新提交在以后的请求这些信息设置。当然,我也建议缓存(持久)资源,如图像在本地,使用相同的HTTP标头。

如果您有修改(在REST-FUL方式)的服务器端服务的奢侈品,那么你就罚款,只要你执行得很好(从经验,可以节省多达网络的3/4如果服务表现好/解析code的iOS端(返回相应的HTTP状态codeS,避免了串,日期零检查,数字转换,提供查询-ID的,而不是隐串等)。

如果你没有那么奢侈,那么无论该服务至少REST-FUL(其中有很大帮助),或者你必须解决的事情客户端(这是一种痛苦,经常)。

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.

Here's what I thought:

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

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.

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.

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. I know this kinda requires to code the backend logic a second time (Server + CoreData) but is this overkill?
  2. Any limitation that I have under estimated?
  3. Any other idea?

解决方案

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.

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).

So the key is to understand REST and Core Data.

  • 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, ...)

  • 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).

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.

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.

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).

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.

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).

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.

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 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.

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...).

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天全站免登陆