webview缓存页面
❶ wkwebview的缓存设置策略
对于iOS8之后新推出的WKWebView还是有显着的有点相对于传统的UIWebView; 但是对于一些网页的缓存策略就比较苍白了,尽管UIWebView已经有很有的缓存设置策略了,但是对于刚推出的WKWbeView并没有设置缓存的功能;
UIWebView设置缓存的方法:
不过自iOS9之后WKWebView缓存设置的API才正式推出:
types是指存在指定缓存类型的一个集合,包括:
❷ WKWebView网页缓存刷新问题
在开发过程中遇到前端改变图片文字,客户端没有实时刷新出来,抓包发现也没有请求网页相关接口。由于不懂后端的知识,折腾了很久,网上也查找了很多都说需要清除缓存。
这是在网上查找的iOS9以上清除缓存方法
不建议使用上述方法,会浪费用户流量,除非用户手动清除缓存。其实主要原因是后端网页设置的问题,通过head请求获取接口返回信息如下:
上面标粗的是关键,通过测试发现WKWebView是否通过缓存取数据还是重新请求接口取决于 Expires,如上就是缓存时效性是30分钟,想要实时刷新,可以让后端不返回这个字段或者这个过期事件设置短一些,例如1分钟。建议静态网页可以设置长时间,需要实时刷新的建议后端不要设置这个字段,以免客户端无法实时显示。
❸ iOS webView利用NSURLProtocol实现离线缓存
最近公司有一个需求,要对webView(UIWebView)实现缓存机制。即在无网条件下,打开webView页面,能读取到网页,有网情况下,缓存未过期也可以使用本地缓存,加快用户读取网页速度。
实现缓存策略的方案有很多,为了保证有效,可控等多方面因素,本文采用NSURLProtocol来实现该需求,它的优势很多,楼主就不再累述了。
关于NSURLProtocol,网上给出了很多资料,但很多方案都有缺陷,包括github上有star的项目,会遇到在特定情况下,网页加载不出来的问题,导致一直显示空白页。本文成功解决了这些问题,目前该项目已在线上稳定运行。
写这篇文章,一方面为了自己,做一些整理,另一方面如果小伙伴,遇到类似需求后,不至于走太多弯路,所谓前人栽树,后人乘凉。废话不多说了,直接上内容。
首先关于URL Loading System
简单来说, URL Loading System 是iOS一系列网络请求类的集合,包括老的NSConnection和现在流行的NSURLSession,还包括一些请求认证的类,一个sessionConfig的类,还有关于处理请求缓存的类等,当然也包括NSURLProtocol类。
当我们需要拦截URL请求时,我们只要通过 - registerClass: 方法注册我们的NSURLProtocol类,然后去重写NSURLProtocol类中的方法,就能对我们发起的请求做处理。
NSURLProtocol 是一个抽象类,所以使用的时候必须定义一个它的子类:
需要拦截URL的控制器中注册该类:
记得在不需要的时候,及时关闭它:
注意一点:如果是基于 NSURLSession 进行的请求,注册的时候需要注册到 NSURLSessionConfiguration 中:
注册成功之后,需要子类CLURLSessionProtocol去实现抽象方法:
+ (BOOL)canInitWithRequest:(NSURLRequest*)request
此处可以拦截需要处理的URL,已经处理过的请求,需要标记请求是否被处理过,防止死循环
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
这个方法用来统一处理请求 request 对象的,可以修改头信息,或者重定向。没有特殊需要,则直接return request;
如果要在这里做重定向以及头信息的时候注意检查是否已经添加,因为这个方法可能被调用多次,也可以在后面的方法中做。
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest*)a toRequest:(NSURLRequest*)b
判断网络请求是否一致,一致的话使用缓存数据。没需要就调用 super 的方法。
- (void)startLoading
这个方法作用很大,把当前请求的request拦截下来以后,在这个方法里面对这个request做各种处理,比如添加请求头,重定向网络,使用自定义的缓存等。
重点:需要标记已经处理过的 request:
- (void)stopLoading
取消流程
流程图: