YTKNetwork ResponseData Cache 分析

本文详细介绍了YTKNetwork中YTKRequest如何实现响应数据的缓存策略,包括忽略缓存、缓存超时、版本管理等关键步骤。通过检查缓存文件的版本、存在性及超时情况,决定是否发起网络请求或直接使用缓存数据。此外,还展示了如何保存服务器返回的JSON数据到本地文件,并提供了使用YTKRequest缓存模板的示例。
YTKBaseRequest:  封装所有的关于当前网络请求所需要的数据,如: 请求Path、请求方法、请求参数、是否加密、是否签名、请求回调Block ... 

YTKRequest: 封装所有关于缓存请求response data的代码

//YTKRequest缓存请求对象的 start方法

<p class="p1"><span class="s1">- (</span><span class="s2">void</span><span class="s1">)start {</span></p><p class="p1">    </p><p class="p1"><span style="white-space:pre">	</span>//1. 如果当前request对象,【设置了忽略缓存数据】,直接调用YTKBaseRequest的start方法,发起网络请求<span style="white-space:pre">	</span></p><p class="p2"><span class="s2"><span style="white-space:pre">	</span>if</span><span class="s3"> (</span><span class="s2">self</span><span class="s3">.</span><span class="s1">ignoreCache</span><span class="s3">) {</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>    <span style="white-space:pre">	</span>[</span><span class="s2">super</span><span class="s1"> </span><span class="s4">start</span><span class="s1">];</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>    <span style="white-space:pre">	</span></span><span class="s2">return</span><span class="s1">;</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>}</span></p><p class="p3"><span class="s1"></span>
</p><p class="p4"><span class="s1"><span style="white-space:pre">	</span>//2. 如果当前request对象,【没有设置缓存超时时间】,<span style="font-family: monospace; white-space: pre; background-color: rgb(240, 240, 240);">直接调用YTKBaseRequest的start方法,发起网络请求</span><span style="font-family: monospace; white-space: pre; background-color: rgb(240, 240, 240);">	</span></span></p><p class="p2"><span class="s2"><span style="white-space:pre">	</span>if</span><span class="s3"> ([</span><span class="s2">self</span><span class="s3"> </span><span class="s1">cacheTimeInSeconds</span><span class="s3">] < </span><span class="s5">0</span><span class="s3">) {</span></p><p class="p1"><span class="s1"><span style="white-space:pre">		</span>[</span><span class="s2">super</span><span class="s1"> </span><span class="s4">start</span><span class="s1">];</span></p><p class="p1"><span class="s1">        <span style="white-space:pre">	</span></span><span class="s2">return</span><span class="s1">;</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>}</span></p><p class="p3"><span class="s1"></span>
</p><p class="p4"><span class="s3">    <span style="white-space:pre">	</span></span><span class="s1">//3. 查看磁盘文件中保存的【当前请求response data数据文件】的 【缓存版本号】</span></p><p class="p1"><span class="s1">    <span style="white-space:pre">	</span></span><span class="s2">long</span><span class="s1"> </span><span class="s2">long</span><span class="s1"> cacheVersionFileContent = [</span><span class="s2">self</span><span class="s1"> </span><span class="s4">cacheVersionFileContent</span><span class="s1">];</span></p><p class="p1"><span style="white-space:pre">	</span>//注意:【缓存数据的版本号管理】:如果【磁盘文件保存的版本号】 与 【当前request对象指定的版本号】不一致,则执行网络请求获取新的response数据</p><p class="p1"><span class="s2"><span style="white-space:pre">	</span>if</span><span class="s1"> (cacheVersionFileContent != [</span><span class="s2">self</span><span class="s1"> </span><span class="s4">cacheVersion</span><span class="s1">]) {</span></p><p class="p1"><span class="s1">        <span style="white-space:pre">	</span>[</span><span class="s2">super</span><span class="s1"> </span><span class="s4">start</span><span class="s1">];</span></p><p class="p1"><span class="s1">        <span style="white-space:pre">	</span></span><span class="s2">return</span><span class="s1">;</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>}</span></p><p class="p3"><span class="s1"></span>
</p><p class="p4"><span class="s1"><span style="white-space:pre">	</span>//4. 如果磁盘上还没有当前request对象的response缓存数据文件,则执行网络请求</span></p><p class="p1"><span class="s6"><span style="white-space:pre">	</span>NSString</span><span class="s1"> *path = [</span><span class="s2">self</span><span class="s1"> </span><span class="s4">cacheFilePath</span><span class="s1">];</span></p><p class="p5"><span class="s1"><span style="white-space:pre">	</span>NSFileManager</span><span class="s3"> *fileManager = [</span><span class="s1">NSFileManager</span><span class="s3"> </span><span class="s1">defaultManager</span><span class="s3">];</span></p><p class="p1"><span class="s2"><span style="white-space:pre">	</span>if</span><span class="s1"> (![fileManager </span><span class="s6">fileExistsAtPath</span><span class="s1">:path </span><span class="s6">isDirectory</span><span class="s1">:</span><span class="s2">nil</span><span class="s1">]) {</span></p><p class="p1"><span class="s1">        <span style="white-space:pre">	</span>[</span><span class="s2">super</span><span class="s1"> </span><span class="s4">start</span><span class="s1">];</span></p><p class="p1"><span class="s1">        <span style="white-space:pre">	</span></span><span class="s2">return</span><span class="s1">;</span></p><p class="p1"><span class="s1">    <span style="white-space:pre">	</span>}</span></p><p class="p3"><span class="s1"></span>
</p><p class="p4"><span class="s1"><span style="white-space:pre">	</span>//5. 【 缓存文件的超时管理 】</span></p><p class="p4"><span style="white-space:pre">	</span>//获取磁盘的缓存response数据文件,从创建到当前时间的时间差</p><p class="p1"><span class="s2"><span style="white-space:pre">	</span>int</span><span class="s1"> seconds = [</span><span class="s2">self</span><span class="s1"> </span><span class="s4">cacheFileDuration</span><span class="s1">:path];</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>//判断缓存文件是否超时</span></p><p class="p1"><span class="s2"><span style="white-space:pre">	</span>if</span><span class="s1"> (seconds < </span><span class="s5">0</span><span class="s1"> || seconds > [</span><span class="s2">self</span><span class="s1"> </span><span class="s4">cacheTimeInSeconds</span><span class="s1">]) {</span></p><p class="p1"><span class="s1"><span style="white-space:pre">		</span>[</span><span class="s2">super</span><span class="s1"> </span><span class="s4">start</span><span class="s1">];</span></p><p class="p1"><span class="s1">        <span style="white-space:pre">	</span></span><span class="s2">return</span><span class="s1">;</span></p><p class="p1"><span class="s1">    <span style="white-space:pre">	</span>}</span></p><p class="p3"><span class="s1"></span>
</p><p class="p4"><span class="s1"><span style="white-space:pre">	</span>//加载缓存文件的response data </span></p><p class="p5"><span class="s4"><span style="white-space:pre">	</span>_cacheJson</span><span class="s3"> = [</span><span class="s1">NSKeyedUnarchiver</span><span class="s3"> </span><span class="s1">unarchiveObjectWithFile</span><span class="s3">:path];</span></p><p class="p1"><span class="s2"><span style="white-space:pre">	</span>if</span><span class="s1"> (</span><span class="s4">_cacheJson</span><span class="s1"> == </span><span class="s2">nil</span><span class="s1">) {</span></p><p class="p1"><span class="s1"><span style="white-space:pre">		</span>[</span><span class="s2">super</span><span class="s1"> </span><span class="s4">start</span><span class="s1">];</span></p><p class="p1"><span class="s2"><span style="white-space:pre">		</span>return</span><span class="s1">;</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>}</span></p><p class="p3"><span class="s1"></span>
</p><p class="p3"><span style="white-space:pre">	</span>//标识数据来自缓存文件</p><p class="p2"><span class="s1"><span style="white-space:pre">	</span>_dataFromCache</span><span class="s3"> = </span><span class="s2">YES</span><span class="s3">;</span></p><p class="p2"><span class="s3">
</span></p><p class="p2"><span class="s3"><span style="white-space:pre">	</span>//结束此次请求</span></p><p class="p2"><span class="s3"><span style="white-space:pre">	</span>[</span><span class="s2">self</span><span class="s3"> </span><span class="s1">requestCompleteFilter</span><span class="s3">];</span></p><p class="p2"><span class="s3">
</span></p><p class="p2"><span class="s3"><span style="white-space:pre">	</span>//执行回调</span></p><p class="p1"><span class="s4"><span style="white-space:pre">	</span>YTKRequest</span><span class="s1"> *strongSelf = </span><span class="s2">self</span><span class="s1">;</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>[strongSelf.</span><span class="s4">delegate</span><span class="s1"> </span><span class="s4">requestFinished</span><span class="s1">:strongSelf];</span></p><p class="p2"><span class="s2"><span style="white-space:pre">	</span>if</span><span class="s3"> (strongSelf.</span><span class="s1">successCompletionBlock</span><span class="s3">) {</span></p><p class="p1"><span class="s1"><span style="white-space:pre">		</span>strongSelf.</span><span class="s4">successCompletionBlock</span><span class="s1">(strongSelf);</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>}</span></p><p class="p1"><span class="s1">
</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span>//清除Block引用</span></p><p class="p2"><span class="s3"><span style="white-space:pre">	</span>[strongSelf </span><span class="s1" style="font-family: Arial, Helvetica, sans-serif;">clearCompletionBlock</span><span class="s3" style="font-family: Arial, Helvetica, sans-serif;">];</span></p><p class="p1"><span class="s1">}</span></p><p class="p1">
</p>

YTKRequest保存请求到的服务器json到本地文件:
<p class="p1"><span class="s1">- (</span><span class="s2">void</span><span class="s1">)saveJsonResponseToCacheFile:(</span><span class="s2">id</span><span class="s1">)jsonResponse {</span></p><p class="p1"><span class="s1"><span style="white-space:pre">	</span></span></p><p class="p1">    //保存json条件:1.当前对象使使用缓存功能 2.当前json不是来自缓存文件,而是服务器</p><p class="p2"><span class="s3">    </span><span class="s2">if</span><span class="s3"> ([</span><span class="s2">self</span><span class="s3"> </span><span class="s1">cacheTimeInSeconds</span><span class="s3">] > </span><span class="s4">0</span><span class="s3"> && ![</span><span class="s2">self</span><span class="s3"> </span><span class="s1">isDataFromCache</span><span class="s3">]) {</span></p><p class="p1"><span class="s1">        </span><span class="s5">NSDictionary</span><span class="s1"> *json = jsonResponse;</span></p><p class="p1"><span class="s1">        </span><span class="s2">if</span><span class="s1"> (json != </span><span class="s2">nil</span><span class="s1">) {</span></p><p class="p1"><span class="s1">
</span></p><p class="p1">            // 把服务器json保存到本地文件</p><p class="p3"><span class="s3">            [</span><span class="s1">NSKeyedArchiver</span><span class="s3"> </span><span class="s1">archiveRootObject</span><span class="s3">:json </span><span class="s1">toFile</span><span class="s3">:[</span><span class="s2">self</span><span class="s3"> </span><span class="s6">cacheFilePath</span><span class="s3">]];</span></p><p class="p3"><span class="s3">
</span></p><p class="p3"><span class="s3"><span style="white-space:pre">	</span>    // 将当前请求对象给定的 【版本号】写入到 【缓存文件.version】中,标识磁盘缓存文件的当前版本号</span></p><p class="p3"><span class="s3">            [</span><span class="s1">NSKeyedArchiver</span><span class="s3"> </span><span class="s1">archiveRootObject</span><span class="s3">:</span><span class="s4">@(</span><span class="s3">[</span><span class="s2">self</span><span class="s3"> </span><span class="s6">cacheVersion</span><span class="s3">]</span><span class="s4">)</span><span class="s3"> </span><span class="s1">toFile</span><span class="s3">:[</span><span class="s2">self</span><span class="s3"> </span><span class="s6">cacheVersionFilePath</span><span class="s3">]];</span></p><p class="p1"><span class="s1">        }</span></p><p class="p1"><span class="s1">    }</span></p><p class="p1"><span class="s1">}</span></p>



使用YTKRequest缓存的模板:

<p class="p1"><span class="s1">- (</span><span class="s2">void</span><span class="s1">)loadCacheData {</span></p><p class="p2"><span class="s1">    </span></p><p class="p3"><span class="s5">    </span><span class="s1">GetUserInfoApi</span><span class="s5"> *api = [[</span><span class="s1">GetUserInfoApi</span><span class="s5"> </span><span class="s3">alloc</span><span class="s5">] </span><span class="s1">initWithUserId</span><span class="s5">:userId];</span></p><p class="p2"><span class="s1">    </span></p><p class="p4"><span class="s6">    </span><span class="s7">//</span><span class="s1">指定读取,当前请求对象的,指定版本号对应的 缓存数据</span></p><p class="p4"><span class="s6">    </span><span class="s7">//【</span><span class="s1">当前缓存文件中保存的版本号】</span><span class="s7"> != 【</span><span class="s1">当前请求对象指定的版本号】 ===》不使用缓存JSON数据</span></p><p class="p4"><span class="s1">
</span></p><p class="p3"><span class="s5">    </span><span class="s2">if</span><span class="s5"> (![api </span><span class="s1">isCacheVersionExpired</span><span class="s5">]) {</span></p><p class="p3"><span class="s5">
</span></p><p class="p3"><span class="s5"><span style="white-space:pre">	</span>//本地缓存文件保存response data</span></p><p class="p1"><span class="s1">        </span><span class="s3">NSDictionary</span><span class="s1"> *cacheJson = [api </span><span class="s8">cacheJson</span><span class="s1">];</span></p><p class="p2"><span class="s1">        </span></p><p class="p5"><span class="s5">        </span><span class="s1">//</span><span class="s9">第一次回传缓存</span><span class="s1">json</span></p><p class="p1"><span class="s1">        </span><span class="s2">if</span><span class="s1"> (</span><span class="s3">success</span><span class="s1">) {</span></p><p class="p1"><span class="s1">            success(cacheJson);</span></p><p class="p1"><span class="s1">        }</span></p><p class="p1"><span class="s1">    }</span></p><p class="p2"><span class="s1">    </span></p><p class="p2"><span class="s1">    //发起网络请求服务器最新数据</span></p><p class="p3"><span class="s5">    [api </span><span class="s1">startWithCompletionBlockWithSuccess</span><span class="s5">:^(</span><span class="s1">YTKBaseRequest</span><span class="s5"> *request) {</span></p><p class="p6"><span class="s5">        </span><span class="s3">NSLog</span><span class="s5">(</span><span class="s1">@"update ui"</span><span class="s5">);</span></p><p class="p6"><span style="font-family: Arial, Helvetica, sans-serif;">      </span></p><p class="p2"><span style="white-space:pre">	</span>//服务器最新数据</p><p class="p1"><span class="s1">        </span><span class="s3">NSDictionary</span><span class="s1"> *serverJson = request.</span><span class="s8">responseJSONObject</span><span class="s1">;</span></p><p class="p2"><span class="s1">        </span></p><p class="p5"><span class="s5">        </span><span class="s1">//</span><span class="s9">第二次回传服务器最新</span><span class="s1">json</span></p><p class="p1"><span class="s1">        </span><span class="s2">if</span><span class="s1"> (success) {</span></p><p class="p1"><span class="s1">            success(serverJson);</span></p><p class="p1"><span class="s1">        }</span></p><p class="p2"><span class="s1">        </span></p><p class="p1"><span class="s1">    } </span><span class="s8">failure</span><span class="s1">:^(</span><span class="s8">YTKBaseRequest</span><span class="s1"> *request) {</span></p><p class="p1"><span class="s1">        </span><span class="s3">NSLog</span><span class="s1">(</span><span class="s4">@"failed"</span><span class="s1">);</span></p><p class="p1"><span class="s1">    }];</span></p><p class="p1"><span class="s1">}</span></p>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值