客户端 (iOS) 上的 Core Data 缓存来自服务器的数据策略

2024-02-17

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

这是我的想法:

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

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

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

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

现在我向各位大神提出一个问题:

  1. 我知道这需要再次编写后端逻辑(服务器+ CoreData),但这是否矫枉过正?
  2. 我有什么低估的限制吗?
  3. 还有其他想法吗?

首先,如果您是注册的 iOS 开发人员,您应该有权参加 WWDC 2010 会议。其中一场会议涵盖了您正在谈论的一些内容:“会议 117,构建服务器驱动的用户体验”。你应该能够在 iTunes 上找到它 http://developer.apple.com/videos/wwdc/2010/.

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

所以关键是理解REST和Core Data。

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

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

如果您计划为您提到的任务实现可重用的 API,您应该确保您了解 REST 和核心数据,因为这可能是您进行最多编码的地方。 (现有 API -ASIHttp请求 http://allseeing-i.com/ASIHTTPRequest/对于网络层(或任何其他层)和任何好的 JSON 库(例如SBJSON http://code.google.com/p/json-framework/)用于解析就可以完成这项工作。

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

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

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

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

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

如果上市时间是您的首要任务,那么您最好采用简单而务实的方法:不要介意可重用性,只需记住所学到的知识,并在下一个项目中进行重构,到处重用和修复代码。最后,所有经验的总和可能会具体化为 API 如何工作以及它提供什么的清晰愿景。如果您还没有做到这一点,请不要尝试将其纳入项目预算,并尝试重用尽可能多的稳定的第 3 方 API。

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

客户端 (iOS) 上的 Core Data 缓存来自服务器的数据策略 的相关文章

  • 如何使用 Core Graphics 在我的触摸位置绘制一个圆圈?

    新程序员来了 我在尝试使用 Core Graphics 在触摸位置周围绘制描边弧时遇到问题 我有绘制圆圈的方法工作正常 并且我已经测试并在点击屏幕时注册触摸 但是当我尝试在点击时调用绘制圆圈的方法时 我收到错误 CG ContextBlah
  • AWS S3 公共对象与私有对象?

    回到 S3 我的存储桶中有图像的 URL 我将在我的应用程序中呈现这些图像 但它们被设置为私有 当我尝试单击该链接时 它显示 访问被拒绝 当我将链接的设置更改为公共时 它会通过 但是我读到公共访问并不是最安全的事情 所以这本质上是一个由两部
  • 如何将相机中的图像保存到 iPhone 图库中的特定文件夹?

    嘿 我是 iPhone 新手 最近我一直在尝试制作一个应用程序 基本上 我想要做的是 如果用户将从相机捕获任何图像 那么它应该保存在设备库中 我知道如何将照片保存在图库中 它对我有用 但我无法将所有捕获的图像保存到设备图库中的特定文件夹 例
  • iOS 上的 UIBezierPath 操作

    我从一条直线开始 我希望用户能够触摸并拖动该线 使其弯曲 实际上 他们有能力将线条操纵成波浪形状 我不确定从技术上实现这一目标的最简单方法 我首先创建了三次曲线的 UIBezierPaths 数组 目的是操纵控制点 但似乎一旦绘制了 UIB
  • UIDocumentInteractionController 阻止“打开方式”表中的空投

    在我的应用程序中 我允许用户通过 Instagram 分享照片 这需要使用 UIDocumentInteractionController 如果手机支持 则会自动检测空投 如何将其从 打开方式 操作表中删除 即使我使用 UIActivity
  • Objective-c 中的块递归

    当执行涉及 Objective C 块的递归时 我在 iOS 应用程序中收到 EXC BAD ACCESS 信号 这是简化的代码 void problematicMethod FriendInfo friendInfo onComplete
  • 为什么我不能在 Realm 属性上使用 private

    我正在尝试在 RealmSwift 中存储一个枚举案例 但 Realm 不支持枚举 本文 https medium com it works locally persisting swift enumerations with realm
  • 推入 UINavigationController 时隐藏 FBFriendPickerViewController 导航栏

    介绍一个实例FBFriendPickerViewController using presentViewController animated completion 非常简单 该类似乎是针对该用例的 但是 我想推送一个实例FBFriendP
  • 所需框架与静态库

    构建现代框架 https developer apple com videos play wwdc2014 416 says 每个应用程序都有自己的自定义框架副本 https stackoverflow com a 15262463 242
  • 为什么这个谓词格式会变成 '= nil'

    有人建议这个线程 https stackoverflow com questions 40686005 nspredicate crash after swift 3 migration与我的问题完全相同 但是 我的应用程序没有崩溃 并且我
  • 以编程方式触发iOS摇动事件

    如何以编程方式触发 iOS 中的摇动事件 我尝试过以下方法 但它总是崩溃 void shake NSLog TEST UIMotionEventProxy m NSClassFromString UIMotionEvent alloc in
  • 我的游戏中应该有多少个视图控制器?

    我开始使用 spritekit 构建我的第一个游戏 现在我只有一个视图控制器来呈现开始屏幕场景 override func viewDidLoad super viewDidLoad let scene StartScreenScene C
  • 我怎样才能勾勒出文本字体?

    我想在边框 轮廓 中显示另一种颜色的文本 我正在尝试使用在 MapOverlayView 中显示文本 text drawAtPoint CGPointMake 0 30 withFont UIFont fontWithName Helvet
  • 频繁绘制 CGPath 时的性能

    我正在开发一个将数据可视化为折线图的 iOS 应用程序 该图被绘制为CGPath在全屏自定义中UIView最多包含 320 个数据点 数据经常更新 图表需要相应地重新绘制 刷新率为 10 秒就很好了 到目前为止很容易 然而 我的方法似乎需要
  • NVActivityIndi​​catorView 仅适用于特定视图

    我正在使用这个库https github com ninjaprox NVActivityIndi catorView https github com ninjaprox NVActivityIndicatorView用于显示加载指示器
  • WhatsApp 显示警告“此项目无法共享。请选择其他项目。”对于 iOS 应用程序。

    我正在开发一个 iOS 应用程序 在该应用程序中 我有社交共享功能 并且社交共享功能使用深度链接来共享 URL 该网址共享对于所有应用程序都运行良好 除了WhatsApp 它会显示一个警报弹出窗口 此项目无法共享 请选择其他项目 以下是我的
  • 避免 UIImage 的 imageNamed - 内存管理

    我正在经历这个链接 http akosma com 2009 01 28 10 iphone memory management tips 我遇到了一个点避免 UIImage 的 imageNamed 出于什么原因我们应该避免这种情况 它会
  • 如何反转 CGPath 的点顺序

    我想画一个圆圈 并用它打出字母 为此 我需要顺时针抚摸圆圈 逆时针抚摸字母 这一切都很好 但是当我使用 Core Text 获取字母路径时 我不知道如何从本质上反转该路径 不是镜像或旋转或任何东西 这很简单 我希望点笔画顺序是逆时针的 这实
  • 分发内部业务 IOS 应用程序

    我遇到了 IOS 应用程序分发的一个令人困惑的部分 因此 我需要简单细分一下我的限制 即仅将我的应用程序分发给我的员工 同事或任何被视为 内部 的人 这是表明我不希望该应用程序出现在应用程序商店中的另一种方式 我的情况是我为几家公司开发 他
  • 为什么使用 iPhone 或 iOS 设备在“iframe”中查看“position:fixed”时不起作用?

    我研究过 stackoverflow 似乎position fixed在 iOS 移动设备的 iframe 中 https stackoverflow com questions 15874910 position fixed and if

随机推荐

  • Segue 未获取选定的行号

    我正在将数据从表视图控制器传递到详细视图 我尝试使用indexPath row直接在我的prepareForSegue方法 但是它显示错误 使用未解析的标识符 indexPath 因此 在搜索网络后 我设置了变量indexOfSelecte
  • 如何在 Android 版 Eclipse 中启用 LogCat/Console?

    在 Android 中编写一个简单的程序时 我错误地关闭了 LogCat 窗口 我想知道如何再次显示它 在 Eclipse 中 转到 窗口 gt 显示视图 gt 其他 gt Android gt Logcat Logcat 只是模拟器或设备
  • Excel VBA 在表格下方添加数据时扩展表格

    我在 Excel 中有一个表格 当用户在表格后添加数据时 该数据不属于该表格 我创建了一个可以执行来扩展表的代码 代码如下 Sub ExtendTableToLastRow Sheets Update Select If ActiveShe
  • 如何使用 Woocommerce WC_AJAX 类

    我正在开发一个基于 Wordpress WooCommerce 的商店 我使用ajax来调用数据 但我是通过 wp admin admin ajax php 在 function php 文件中使用我自己的函数来完成此操作 昨天我在 woo
  • ruby:“p *1..10”中的星号是什么意思

    the line p 1 10 做完全相同的事情 1 10 each x puts x 这将为您提供以下输出 ruby e p 1 10 1 2 3 4 5 6 7 8 9 10 例如 在使用 textmate 时 这是一个很好的快捷方式
  • 如何在ListView中正确使用TextSwitcher?

    My TextSwitcher对于每条记录ListView应显示第一个值 text1 然后是另一个值 text2 然后再次首先值 依此类推 仅当以下情况时才会发生text2不是空的 否则text1应始终显示 没有任何更改和动画 我已经创建了
  • log4j2.xml中每个包的Log4J不同日志级别

    我有一个 Java Web 应用程序log4j2 xml我需要为每个包设置不同的级别 例如 com myexample firstmodule 这应该是INFO level com myexample secondmodule 这应该是TR
  • 如何在 Python 中停止打印 OpenCV 错误消息

    Same as 这个问题在这里 https stackoverflow com questions 17567808 how to suppress opencv error message 17575610 17575610 除了 Pyt
  • 使用 DOM 解析 HTML 时保留文件偏移量?

    我要修改 img src 格式不太畸形的 HTML 中的属性 WordPress 帖子 我知道我可以采取简单的方法并使用正则表达式 但我担心穿着蓝色毛茸茸的衣服的人会在我睡梦中困扰我 https meta stackexchange com
  • 如何将字符串数据框列转换为日期时间作为年和周的格式?

    样本数据 Week Price 2011 31 1 58 2011 32 1 9 2011 33 1 9 2011 34 1 9 我有一个像上面这样的数据框 我想将 周 列类型从字符串转换为日期时间 My Code data Date Ti
  • 动态郎。运行时与反射

    我计划在我的新项目中使用动态关键字 但在介入之前 我想了解使用动态关键字而不是反射的优点和缺点 在专业人士的帮助下 我可以找到关于动态关键字的信息 可读 可维护的代码 更少的代码行 虽然与使用动态关键字相关的负面影响 我听到的是 影响应用程
  • 将 django 查询集转换为数组

    我想将 django 查询集转换为数组 例如 firstnames Users objects values firstnames 得到看起来像的结果 firstnames Nancy Andrew Janet Margaret Steve
  • 以下哪个 SQL 查询会更快?两个表或连续查询的联接?

    我这里有两张桌子 ITEMS ID DETAILS OWNER USERS ID NAME Where ITEMS OWNER USERS ID 我列出了这些物品及其各自所有者的姓名 为此 我可以在两个表上使用联接 或者我可以选择所有 IT
  • Conda 报告 PackagesNotFoundError: python=3.1 for reticulate 环境

    我正在尝试在 R 中使用 python 包 但我不断收到相同的错误 ImportError cannot import name read csv from pandas unknown location 我也不能使用 py install
  • 尝试改进 haskell 中当前处理列表的丑陋代码

    我正在尝试在 Haskell 中实现一个函数 该函数将采用任意整数列表xs和一个整数k 并返回一组列表k在所有可能的位置 例如 对于一个xs 0 1 and k 2 我们会有 myFunction 0 1 2 2 0 1 0 2 1 0 1
  • 作为配置属性的不可变类型

    是否可以使用不可变类型作为 NET 配置 API 的配置属性 假设我有一个名为 MyClass 的不可变类型 public class ImmutableClass private readonly int value public Imm
  • 弹性盒| Flex 项目被推出包含 div (屏幕外)

    我正在使用弹性盒布局 https css tricks com snippets css a guide to flexbox 设置过去任务列表的样式 任务描述和时间的长度总是变化很大 一切看起来都很棒 直到输入足够长的任务描述以换行到第二
  • 查找嵌套映射中特定键的值

    在 Clojure 中 如何找到可能位于嵌套映射结构深处的键的值 例如 def m a b b c c d e e f f find nested m f gt f Clojure 提供tree seq http conj io store
  • Firebase 中一个应用程序的多个项目:如何指定 Android 包名称

    我已经在生产环境中设置了 Firebase 项目 我想为我的 firebase 应用程序创建一个开发环境 我看到有很多关于此的文档 我需要根据文档获取 google services json 要获取 google services jso
  • 客户端 (iOS) 上的 Core Data 缓存来自服务器的数据策略

    我编写了许多与后端通信的 iOS 应用程序 几乎每次 我都使用 HTTP 缓存来缓存查询并将响应数据 JSON 解析为 Objective C 对象 对于这个新项目 我想知道核心数据方法是否有意义 这是我的想法 iOS 客户端向服务器发出请