文章介绍了使用NSURLProtocol实现UIWebView的离线缓存的简单实现,你可以在github上下载这个demo的代码。

无论是“MKNetworkKit”还是”AFCache”实现的缓存都过于复杂,而他想要的是一个简单机制:

1、你使用了UIWebView指向来显示一个有图像嵌入的网站。
2、当你的设备online时,你有正常的缓存算法。
3、当你的设备offline时,你可以显示页面的最后一个版本。

这个demo里做了一个很简单的测试:将cnn.com运行一次,然后再将网络断掉,去浏览这些数据。

现有解决方案:

Matt Gallagher 有一些有趣的想法,使用NSURLCache的子类来实现,但是Rob发现这是不可靠的,尤其是iOS5的HTTP缓存规则十分复杂,在许多情况下如果你不访问服务器便不能获知你缓存的数据是否有效。另外,一些必要的素材如果没有被缓存,那么在离线时前期做的缓存工作就实效了。

AFCache也被认为是一个很好的解决方案(辉:有时间我会对这个开源库进行详细评估,表面上看就是connection、NSURLCache、NSURLProtocol的综合解决方案)。短时间内作者并没有使测试通过,但是AFCache的作者也在文章后边回复说,采纳了Rob的想法,已经提交代码到github上。

要点:
1、尽早注册你的URLProtocol(application:didFinishLaunchingWithOptions:)。
2、NSURLProtocol是NSURLConnection的handler。NSURLConnection的每个请求都会去便利所有的Protocols,并询问你能处理这个请求么(canInitWithRequest: )。如果这个Protocol返回YES,则第一个返回YES的Protocol会来处理这个connection。Protocols的遍历是反向的,也就是最后注册的Protocol会被优先判断。
3、 当你的handler被选中了,connection就会调用–> initWithRequest:cachedResponse:client:,紧接着会调用–>startLoading。然后你需要负责回调:–>URLProtocol:didReceiveResponse:cacheStoragePolicy:,有些则会调用:–>URLProtocol:didLoadData:, 并且最终会调用–>URLProtocolDidFinishLoading:。你有没有发现这些方法和NSURLConnection delegate的方法非常类似——这绝非偶然!
4、当online的情况下,RNCachingURLProtocol只是负责将请求转发给一个新的NSURLConnection,并且拷贝一份结果给原来的connection。offline时, RNCachingURLProtocol就会从磁盘里载入先前的结果,并将这些数据发回给连接。整个过程只有区区200行代码(不包含Reachability)。
5、这里还有一个有趣的问题,就是当RNCachingURLProtocol创建了一个新的NSURLConnection的,即新的connection也会去找一个handler。 如果RNCachingURLProtocol说可以处理,那么就死循环了。怎么解决呢?通过添加自定义HTTP Header(X-RNCache)来标记这个请求,告诉RNCachingURLProtocol不要再处理这个请求。
6、它可以响应所有的connection,所以你可能需要修改canInitWithRequest:来 选择你要缓存的数据。

另外:并发请求或复杂网络请求的缓存请使用MKNetworkKit(我们也在一个项目中使用了这个类库,非常轻量快捷是ASI的很不错的替代品)。

总结一下:
这项技术不是用来替代AFCache、MKNetworkKit的,他只是用来解决独立的、简单问题的(当然它也可以通过复杂实现来解决复杂问题)。 NSURLProtocol是非常强大的,Rob已经使用它来监听网络流量(如PandoraBoy中的几个ProxyURLProtocol类)。它非常值得你将其添加到你的工具箱中。

实例代码下载:https://github.com/rnapier/RNCachingURLProtocol

参见demo中的类文件:RNCachingURLProtocol.m

一定要看Nick Dowell在评论中回复的对于redirect的解决办法:(Code to fix HTTP redirect handling: https://gist.github.com/1885821)

(NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
if ([response isKindOfClass:[NSHTTPURLResponse class]])
{
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
if ([HTTPResponse statusCode] == 301 || [HTTPResponse statusCode] == 302)
{
NSMutableURLRequest *mutableRequest = [request mutableCopy];
[mutableRequest setURL:[NSURL URLWithString:[[HTTPResponse allHeaderFields] objectForKey:@”Location”]]];
request = [mutableRequest copy];
[[self client] URLProtocol:self wasRedirectedToRequest:request redirectResponse:response];
}
}
return request;
}

使用NSURLProtocol实现UIWebView的离线缓存的简单实现相关推荐

  1. 使用NSURLProtocol实现UIWebView的离线缓存

    https://github.com/rnapier/RNCachingURLProtocol 转载于:https://www.cnblogs.com/spiderdzl/p/5207459.html

  2. 离线缓存之RNCachingURLProtocol解析

    主要功能:实现 网页离线加载.基本思想来源于AFCache.作者是Rob Napier(IOSX Programming的作者). 使用方法: To build, you will need the ...

  3. 源码推荐:移动端商城(微信小程序源代码) WebView离线缓存

    移动端商城(微信小程序源代码)(上传者:腾讯攻城师jack) 功能包括:商品橱窗,商品搜索,购物车,结账等功能. TableView嵌套webView自适应高度(上传者:linlinchen) tab ...

  4. iOS原生App与H5页面交互 离线缓存 笔记

    //webview每次加载之前都会调用这个方法,利用该代理方法截取JS的href来调用原生的方法- (BOOL)webView:(UIWebView*)webView shouldStartLoadW ...

  5. 关于域用户的离线缓存登录知识分享

    关于域用户的离线缓存登录知识分享 微软设计缓存登录的目的? 缓存登录主要是为了解决当公司域控制器发生故障联系不上DC或用户拿笔记本电脑回家不拔×××的情况下,依然能够登录到系统,进行办公.如果用户登录 ...

  6. 离线缓存占内存吗_彻底弄懂浏览器缓存策略

    浏览器缓存策略对于前端开发同学来说不陌生,大家都有一定的了解,但如果没有系统的归纳总结,可能三言两语很难说明白,甚至说错,尤其在面试过程中感触颇深,很多候选人对这类基础知识竟然都是一知半解,说出几个概 ...

  7. html开启页面离线缓存,HTML5 离线缓存

    离线缓存 applicationCache 第一次加载后将数据缓存,如果没有清除缓存,下一次没有网络也能加载. 使用 1. 使用 manifest 属性,引入 .appcache 文件 每个指定了 m ...

  8. html5 客户端数据缓存机制,深入理解HTML5离线缓存机制

    TML5提供了一种离线应用缓存机制,使得网页应用可以离线使用,这种机制在移动端浏览器上支持度非常广,所有版本的android和ios浏览器都能很好的支持.我们可以放心的使用该特性来加速移动端页面的访问 ...

  9. javascript中本地储存、离线缓存、地理定位、网络状态

    本地储存: 实际开发中某些内容是不需要放到服务器中,而是放到了浏览器中,需要的时候可以快速的访问,甚至页面刷新也可能不会丢失数据,容量较大:这里介绍两种数据存储方式:sessionStorage约5M ...

最新文章

  1. 【HDOJ】3006 The Number of set
  2. matlab mpt工具箱帮助文档_替代 Matlab 的国产软件出现?
  3. eclipse android 第一个程序,Eclipse 开发 Android,第一个 HelloWord 程序(学习1)-Fun言
  4. 高速公路车路协同网络需求研究
  5. dnf时装补丁教程_【时装补丁制作】消灭伸手党!最详细的图文教程~
  6. java电影推荐系统_基于Mahout的电影推荐系统
  7. 移动硬盘与电脑连接后 计算机中找不到,移动硬盘连接电脑后不显示盘符怎么办...
  8. 将java 文件夹里面的.java 文件 拷贝到temp文件夹下,并且修改后缀名为.txt
  9. 几款远程登录软件的对比
  10. C++读取netcdf文件
  11. web的邮件抄送和密送
  12. 大数据采集方法有哪些
  13. android之图片选择器ImageSelector的使用
  14. 智慧农业“黑科技”,FCU1101智能灌溉控制器解决方案
  15. jQuery幸运大转盘
  16. 《Linux那些事儿之我是USB》我是U盘(4)想到达明天现在就要启程
  17. 利用python实现空格消除
  18. [渝粤教育] 中国地质大学 机械设计 复习题 (2)
  19. 计算机科学世界第13,计算机专业世界排名:麻省理工第1名,清华第13名,北大第19名!...
  20. 945G显卡打开XGL

热门文章

  1. ef 数据迁移mysql_Windows下重装xampp并做MySQL数据迁移的步骤
  2. linux vim 高亮查找,vim技巧:用列表形式显示所有搜索到的内容,去掉搜索内容的高亮...
  3. 笔记本电脑没有鼠标怎么右键_联想笔记本电脑没有声音怎么修复
  4. php asp.net des,转DES的dotNet到php实现
  5. ios 百度地图指定区域_ios百度地图的使用(普通定位、反地理编码)
  6. 牛客练习赛26 E-树上路径 (树链剖分+线段树)
  7. eggjs的参数校验模块egg-validate的使用和进一步定制化升级
  8. PHP常用方法很有意义的博客网址
  9. centos 安装 acrobat Reader之后
  10. HDU- 最大报销额