`
CshBBrain
  • 浏览: 637503 次
  • 性别: Icon_minigender_1
  • 来自: 成都
博客专栏
B7d9bf34-126e-301f-819e-81f2615b5a2a
开源WebSocket服务...
浏览量:142024
Group-logo
HTML5移动开发
浏览量:135347
社区版块
存档分类
最新评论

使用NSURLProtocol实现UIWebView的离线缓存

 
阅读更多

转自:http://www.appfanr.com/2012/07/use-nsurlprotocol-uiwebview-offline-cache/

 

搜索解决方案的时候找到了Rob Napier 的博文:Drop-in offline caching for UIWebView (and NSURLProtocol) 文章介绍了使用NSURLProtocol实现UIWebView的离线缓存的简单实现,你可以在github上下载这个demo的代码。

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

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

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

现有解决方案:

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

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

 

如果你有兴趣的话可以读一下我这篇小文:NSURLCache实现离线阅读的一点小心得

分享到:
评论

相关推荐

    ios-基于NSURLSession NSURLProtol的UIWebView离线缓存.zip

    基于NSURLSession NSURLProtol的UIWebView离线缓存 主要是使用苹果的黑魔法类:NSURLProtocol来对网络请求进行拦截,拦截后使用自定义的网络去加载数据后进行离线缓存。这样保证在没有网络的情况下,也能保证离线能...

    UIWebView离线缓存

    代码测试了一台ipad2(IOS 5.1),一台5s(IOS 7.0.4)都可以正常缓存.

    ios-基于NSURLSession和NSURLProtocol的webView缓存.zip

    基于NSURLSession NSURLProtol的UIWebView离线缓存 主要是使用苹果的黑魔法类:NSURLProtocol来对网络请求进行拦截,拦截后使用自定义的网络去加载数据后进行离线缓存。这样保证在没有网络的情况下,也能保证离线能...

    UIWebView 离线浏览(iPhone源代码)

     实现 UIWebView 的离线浏览(缓存)功能。 作者说: 原理:将get请求的数据缓存在本地cache目录中,以后访问的时候直接从cache中获取数据。 备注:在初始化缓存的时候可以指定缓存的有效期时间长度,具体参看...

    iOS UIWebView的缓存

    实现UIWebView缓存图片还有文字,在无网的条件下依然可以加载,实现在无网的条件下从本地加载

    UIWebView缓存网页

    利用UIWebView下载缓存网页,离线情况下也可以看之前下载过的网页

    IOS 离线浏览网页

    通过网页浏览时,讲缓存保存起来,若下次离线浏览该网页,则显示之前保存的数据;...本代码在http://code4app.com/ios/UIWebView离线缓存/53c39db6933bf07c388b49c8 的基础上面做小修改,希望能对大家有用

    [转] 为UIWebView实现离线浏览

    NULL 博文链接:https://re-reference.iteye.com/blog/1391408

    iOS-UIWebview缓存并保证实时性

    iOS-UIWebview缓存并保证实时性 详细解释:http://blog.csdn.net/u014220518/article/details/72380291 欢迎关注!

    UIWebview使用缓存并且保证实时性

    UIWebview中提供的缓存策略 NSURLRequestUseProtocolCachePolicy 缓存策略定义在 web 协议实现中,用于请求特定的URL。是默认的URL缓存策略。 NSURLRequestReloadIgnoringLocalCacheData 从服务端获取数据,忽略...

    浅谈iOS UIWebView对H5的缓存功能

    之前做的都是加载的静态的web页面,交互调试起来很快,这次搞的是js写的前端页面,跳转什么的都是动态的,然后就不响应了,搞了半天原来是缓存的问题,这里简单介绍一下,一般请求会使用下面的方法: + ...

    UIWebView的使用代码

    之前提到UIWebView使用一个UIScrollView对象来关联web页面的内容,通过UIWebView的scrollView属性即可获得该对象,默认情况下网页长度超出设备视口长度后页面会滚动,用户使用手指滚动页面到页面边距并放开手指后...

    UIWebView实现图文混排

    UIWebView实现图文混排

    swift-两步实现iOSUIWebView通过cookie完成自动登录。

    两步实现iOS UIWebView 通过 cookie 完成自动登录。

    UIWebView+html+css

    UIWebView+html+css,实现UIWebView中可点击链接,并且可显示gif动画效果

    UIWebView的使用

    这是我在学习ios的过程中写的一个demo,使用UIWebView实现一个简单的浏览器

    HTXSCookieURLProtocol:使用NSURLProtocol同步Cookie

    HTXSCookieURLProtocol 使用场景: 客户端与 UIWebView 中的 HTML 页面需要同步登录态时,如果...该项目通过子类 NSURLProtocol 实现 URL 加载时,向符合条件的 URL 注入本地已保存的 Cookies 已达到同步登录态的作用。

    Cocos2dx中UIWebView替换为WKWebView

    IOS开发中因为引入cocos2dx,导致代码审核不通过无法提交( Apple will stop accepting submissions of apps that use UIWebView APIs...具体的修改方式使用以下的文件替换cocoas引擎中的UIWebViewImpl-ios.mm文件即可。

    UIWebView Demo代码

    UIWebView Web 网页 Demo 代码

Global site tag (gtag.js) - Google Analytics