转自: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实现离线阅读的一点小心得
相关推荐
基于NSURLSession NSURLProtol的UIWebView离线缓存 主要是使用苹果的黑魔法类:NSURLProtocol来对网络请求进行拦截,拦截后使用自定义的网络去加载数据后进行离线缓存。这样保证在没有网络的情况下,也能保证离线能...
UIWebView不仅能够实时加载网络页面,还可以实现离线缓存功能,使得用户在没有网络连接时依然可以查看之前加载过的网页内容。这个特性对于提高用户体验,特别是对于那些在网络不稳定或者无网络环境下的应用来说,...
【标题】:“为UIWebView实现离线浏览” 在iOS应用开发中,UIWebView是一个非常重要的组件,它允许我们在应用程序中嵌入网页内容。然而,在没有网络连接的情况下,UIWebView无法加载网页,这限制了用户体验。为了...
基于NSURLSession NSURLProtol的UIWebView离线缓存 主要是使用苹果的黑魔法类:NSURLProtocol来对网络请求进行拦截,拦截后使用自定义的网络去加载数据后进行离线缓存。这样保证在没有网络的情况下,也能保证离线能...
自定义URL协议允许我们拦截HTTP/HTTPS请求,根据需要存储和检索数据,从而实现离线缓存。 具体实现步骤如下: 1. **注册自定义URLProtocol**:在应用程序启动时,需要注册`RNCachingURLProtocol`作为系统的一部分...
本文将深入探讨如何实现UIWebView的缓存功能,以确保离线状态下应用仍能正常运行。 首先,我们需要理解iOS中的缓存系统。iOS提供了URLCache类,这是一个用于处理HTTP请求的缓存系统。当使用UIWebView加载网页时,...
实现 UIWebView 的离线浏览(缓存)功能。 作者说: 原理:将get请求的数据缓存在本地cache目录中,以后访问的时候直接从cache中获取数据。 备注:在初始化缓存的时候可以指定缓存的有效期时间长度,具体参看...
在iOS开发中,UIWebView是用于展示网页内容的重要组件,然而在处理大量数据或网络状况不稳定的情况下,如何实现UIWebView的缓存并确保信息的实时性是一个常见的挑战。本篇文章将深入探讨这个问题,并提供一种解决...
通过网页浏览时,讲缓存保存起来,若下次离线浏览该网页,则显示之前保存的数据;...本代码在http://code4app.com/ios/UIWebView离线缓存/53c39db6933bf07c388b49c8 的基础上面做小修改,希望能对大家有用
UIWebview中提供的缓存策略 NSURLRequestUseProtocolCachePolicy 缓存策略定义在 web 协议实现中,用于请求特定的URL。是默认的URL缓存策略。 NSURLRequestReloadIgnoringLocalCacheData 从服务端获取数据,忽略...
通过子类化`NSURLProtocol`,我们可以拦截、修改或者替换网络请求,甚至可以实现离线缓存、数据加密等功能。在`WebView`中,我们通常会用它来拦截JavaScript发起的HTTP/HTTPS请求。 要实现`WebView`中的`...
本文将深入探讨如何使用UIWebView来实现这一功能。 首先,理解HTTPS双向认证的概念。普通的HTTPS连接是单向认证,服务器通过数字证书证明自己的身份,而客户端无需验证。而在双向认证中,服务器和客户端都需要验证...
2. 使用Service Worker:WKWebView支持Service Worker,它可以实现更高级的离线缓存和数据存储,提供更流畅的离线体验。 3. 利用HTTP首部控制:通过设置适当的"Cache-Control"、"Pragma"、"ETag"等首部字段,指示...
例如,我们可以使用 NSURLRequestReturnCacheDataDontLoad 来使 UIWebView 使用缓存数据,而不重新加载数据。或者,我们可以使用 NSURLRequestReloadIgnoringCacheData 来使 UIWebView 重新加载数据,而不使用缓存...
4. **Service Worker**:在支持的服务员,Service Worker允许开发者创建后台脚本,处理网络请求,实现离线缓存和预加载等功能。不过,iOS的WKWebView目前不支持Service Worker。 为了实现自定义的缓存逻辑,开发者...
之前提到UIWebView使用一个UIScrollView对象来关联web页面的内容,通过UIWebView的scrollView属性即可获得该对象,默认情况下网页长度超出设备视口长度后页面会滚动,用户使用手指滚动页面到页面边距并放开手指后...
当需要在应用中实现图文混排时,UIWebView是一个非常实用的选择,因为它能够轻松地将文字和图片结合在一起显示。本篇文章将详细探讨如何利用UIWebView来实现这一功能。 首先,我们需要理解图文混排的基本概念。图文...
一、UIWebView基本使用 1. 初始化:UIWebView可以通过初始化方法创建,例如`initWithFrame:frame`,指定一个矩形区域作为web视图的大小。 ```swift let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: ...
在iOS开发中,UIWebView是苹果提供的一种非常重要的组件,它允许开发者在应用程序内部嵌入网页内容,实现类似浏览器的功能。这个"UIWebView的使用"示例是一个基础的学习项目,旨在帮助开发者理解如何通过UIWebView...