WKWebView的缓存问题以及如何正确清理缓存
2017-11-16 10:28
543 查看
12.7更新一个问题
当你有一个导航栏控制器,加载了ControllerA,然后Push到ControllerB(而这个B内嵌WKWebView,常规都会注入JS),然后你又Push到了ControllerC(也可以不Push),反正经过了一个WebView,这个时候你从顶部PopRoot,这个时候如果你不把WebView里面的JS移除掉,系统是不会让WebView Dealloc的,一般你手动左上角pop一层一层回去,自然你加了代码移除,就不会有问题,我的问题是,popRoot,不会触发左上角按钮的事件,我的做法是,如果Web跳转原生TabBar,需要切换,而且移除当前控制器所有VC,如果能顺利移除Web,必须加上通知,让Web手动调用移除JS的代码,才能正确Dealloc
这里是常规的Pop,都能正常dealloc,如果PopRoot,不会触发ButtonBack的事件,因此需要通过通知的方式主动触发removeScriptMessageAll,不然这个Web是无法Dealloc的,记录一下,如果有更好的方式,朋友请留言
NSURLCache 为您的应用的 URL 请求提供了内存中以及磁盘上的综合缓存机制。 作为基础类库 URL 加载系统 的一部分,任何通过 NSURLConnection 加载的请求都将被 NSURLCache 处理。
当然系统有默认的,你也可以自己手动初始化并且给需要的大小以及存储沙盒地址,其实AFNetWorking里面就有
这里有个参数diskPath可以写也可以不写,如果默认不写,就是通过我们的BundleID进行路径存储的,如下图,就是默认WKWebView的缓存地址和文件,这两个WebKit的文件就是disk缓存
NSURLRequestUseProtocolCachePolicy: 对特定的 URL 请求使用网络协议中实现的缓存逻辑。这是默认的策略。
NSURLRequestReloadIgnoringLocalCacheData:数据需要从原始地址加载。不使用现有缓存。
NSURLRequestReloadIgnoringLocalAndRemoteCacheData:不仅忽略本地缓存,同时也忽略代理服务器或其他中间介质目前已有的、协议允许的缓存。
NSURLRequestReturnCacheDataElseLoad:无论缓存是否过期,先使用本地缓存数据。如果缓存中没有请求所对应的数据,那么从原始地址加载数据。
NSURLRequestReturnCacheDataDontLoad:无论缓存是否过期,先使用本地缓存数据。如果缓存中没有请求所对应的数据,那么放弃从原始地址加载数据,请求视为失败(即:“离线”模式)。
方法1:NSURLRequestReloadIgnoringCacheData忽略缓存
方法2:即使你用了默认缓存策略,如何清除缓存
NSURLCache是会缓存到内存中以及磁盘中的,那么就非常明确,需要两者都清除
首先,你要理解,这是最低支持iOS 8的解决方案,因为iOS 9以上有针对WKWebView的清缓存API,很显然上面的方法会有弊端。。。。。。以上方法,可以删除jsp的,但是不能删除HTML静态资源的那种,不知道是什么原因,反正我测试了一下,就是无法清除静态资源,反正无法清干净
html和jsp的区别–静态页面和动态页面的区别
iOS 9之后有了新的API
如果最低支持iOS 9,那么用该方法就能完全清除干净,但是第一个为毛不能清除干净,具体知道的朋友可以留言告诉我
方法3:URL更新的时候带上版本号
其实每次你URL没有更新,但是你的内容已经更新了,由于缓存的原因,你还是只能读取缓存,这个时候你让地址都带上版本号,就能区别统一url下缓存了,或者在配置文件带上开关,是否需要清干净缓存访问最新的,一样的道理
当你有一个导航栏控制器,加载了ControllerA,然后Push到ControllerB(而这个B内嵌WKWebView,常规都会注入JS),然后你又Push到了ControllerC(也可以不Push),反正经过了一个WebView,这个时候你从顶部PopRoot,这个时候如果你不把WebView里面的JS移除掉,系统是不会让WebView Dealloc的,一般你手动左上角pop一层一层回去,自然你加了代码移除,就不会有问题,我的问题是,popRoot,不会触发左上角按钮的事件,我的做法是,如果Web跳转原生TabBar,需要切换,而且移除当前控制器所有VC,如果能顺利移除Web,必须加上通知,让Web手动调用移除JS的代码,才能正确Dealloc
- (void)backButtonPressed:(nullable id)sender{ if (self.webView.canGoBack) { [self.webView goBack]; } else{ [self removeScriptMessageAll]; [super backButtonPressed:sender]; } } - (void)removeScriptMessageAll{ [self.webView removeScriptMessageHandlerForName:kWebViewScriptMessageHandlerLoginName]; [self.webView removeScriptMessageHandlerForName:kWebViewScriptMessageHandlerTokenName]; [self.webView removeScriptMessageHandlerForName:kWebViewScriptMessageHandlerUUIDName]; } - (void)dealloc{ [self.webView stopLoading]; self.webView.delegate = nil; [self.webView removeFromSuperview]; [[NSNotificationCenter defaultCenter] removeObserver:self name:MTF_NOTIFICATION_LOGIN_CALLBACK object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self]; NSLog(@"dealloc--->%s",object_getClassName(self)); }
这里是常规的Pop,都能正常dealloc,如果PopRoot,不会触发ButtonBack的事件,因此需要通过通知的方式主动触发removeScriptMessageAll,不然这个Web是无法Dealloc的,记录一下,如果有更好的方式,朋友请留言
NSURLCache 为您的应用的 URL 请求提供了内存中以及磁盘上的综合缓存机制。 作为基础类库 URL 加载系统 的一部分,任何通过 NSURLConnection 加载的请求都将被 NSURLCache 处理。
当然系统有默认的,你也可以自己手动初始化并且给需要的大小以及存储沙盒地址,其实AFNetWorking里面就有
+ (NSURLCache *)defaultURLCache { return [[NSURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024 diskCapacity:150 * 1024 * 1024 diskPath:@"com.alamofire.imagedownloader"]; }
这里有个参数diskPath可以写也可以不写,如果默认不写,就是通过我们的BundleID进行路径存储的,如下图,就是默认WKWebView的缓存地址和文件,这两个WebKit的文件就是disk缓存
NSURLRequestCachePolicy
当WebView加载URL的时候有这个参数, cachePolicy 属性,它根据以下常量指定了请求的缓存行为NSURLRequestUseProtocolCachePolicy: 对特定的 URL 请求使用网络协议中实现的缓存逻辑。这是默认的策略。
NSURLRequestReloadIgnoringLocalCacheData:数据需要从原始地址加载。不使用现有缓存。
NSURLRequestReloadIgnoringLocalAndRemoteCacheData:不仅忽略本地缓存,同时也忽略代理服务器或其他中间介质目前已有的、协议允许的缓存。
NSURLRequestReturnCacheDataElseLoad:无论缓存是否过期,先使用本地缓存数据。如果缓存中没有请求所对应的数据,那么从原始地址加载数据。
NSURLRequestReturnCacheDataDontLoad:无论缓存是否过期,先使用本地缓存数据。如果缓存中没有请求所对应的数据,那么放弃从原始地址加载数据,请求视为失败(即:“离线”模式)。
常量 | 意义 |
---|---|
UseProtocolCachePolicy | 默认行为 |
ReloadIgnoringLocalCacheData | 不使用缓存 |
ReloadIgnoringLocalAndRemoteCacheData | 我是认真地,不使用任何缓存 |
ReturnCacheDataElseLoad | 使用缓存(不管它是否过期),如果缓存中没有,那从网络加载吧 |
ReturnCacheDataDontLoad | 离线模式:使用缓存(不管它是否过期),但是不从网络加载 |
ReloadRevalidatingCacheData | 在使用前去服务器验证 |
清理缓存
如何不用缓存,每次请求最新的Web数据方法1:NSURLRequestReloadIgnoringCacheData忽略缓存
- (void)loadNoCacheData{ NSString *stringurl=[NSString stringWithFormat:@"http://www.baidu.com"]; NSURL *url=[NSURL URLWithString:stringurl]; NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15.0]; [_webView loadRequest:theRequest]; }
方法2:即使你用了默认缓存策略,如何清除缓存
NSURLCache是会缓存到内存中以及磁盘中的,那么就非常明确,需要两者都清除
- (void)clearWbCache{ // (NSHomeDirectory)/Library/Caches/(current application name, [[NSProcessInfo processInfo] processName]) // 清除缓存 [[NSURLCache sharedURLCache] removeAllCachedResponses]; [[NSURLCache sharedURLCache] setDiskCapacity:0]; [[NSURLCache sharedURLCache] setMemoryCapacity:0]; // 清除磁盘(上面两句就是已经执行好了,下面只是一个思路) 路径来源可以看上面的图(不过这里) /* NSString *libraryDir = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES)[0]; NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; NSString *webkitFolderInLib = [NSString stringWithFormat:@"%@/WebKit",libraryDir]; NSString *webKitFolderInCaches = [NSString stringWithFormat:@"%@/Caches/%@/WebKit",libraryDir,bundleId]; NSError *error; [[NSFileManager defaultManager] removeItemAtPath:webKitFolderInCaches error:&error]; [[NSFileManager defaultManager] removeItemAtPath:webkitFolderInLib error:nil]; */ }
首先,你要理解,这是最低支持iOS 8的解决方案,因为iOS 9以上有针对WKWebView的清缓存API,很显然上面的方法会有弊端。。。。。。以上方法,可以删除jsp的,但是不能删除HTML静态资源的那种,不知道是什么原因,反正我测试了一下,就是无法清除静态资源,反正无法清干净
html和jsp的区别–静态页面和动态页面的区别
iOS 9之后有了新的API
// 清除部分,可以自己设置 // NSSet *websiteDataTypes= [NSSet setWithArray:types]; // 清除所有 NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes]; //// Date from NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0]; //// Execute [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{ // Done NSLog(@"清楚缓存完毕"); }];
如果最低支持iOS 9,那么用该方法就能完全清除干净,但是第一个为毛不能清除干净,具体知道的朋友可以留言告诉我
方法3:URL更新的时候带上版本号
其实每次你URL没有更新,但是你的内容已经更新了,由于缓存的原因,你还是只能读取缓存,这个时候你让地址都带上版本号,就能区别统一url下缓存了,或者在配置文件带上开关,是否需要清干净缓存访问最新的,一样的道理
相关文章推荐
- 浅谈iOS中WKWebView和UIWebView的清除缓存问题
- WebView缓存的清理问题
- WKWebView 基本使用及与JS交互,以及低版本系统崩溃问题解决
- WKWebView简单使用及关于缓存的问题
- iOS开发之WKWebView的使用以及遇到的问题
- iOS webView以及WKWebView计算高度慢,加快加载速度等问题
- 关于android 端,人人网以及新浪网 webview 页面缓存问题
- android webview & ios uiwebview和wkwebview的交互以及本地缓存
- android中webview携带cookie以及webview所加载网页中js调用java方法问题
- android WebView与JS交互以及需要注意问题
- Android webview删除缓存问题
- 如何解决Android WebView出现的乱码问题
- 解决Android4.4 webview 图片如何自适应 之前的方法失效问题
- android webview 如何去广告和如何解决重定向返回的问题。
- Android用WebView加载flash大文件偶然会出现内存溢出以及蓝色打问号小方块问题的解决方案
- SDWebImage使用以及缓存和本地存储的清理
- Android开发如何正确使用WebView
- .net 如何在web.config中读取自定义节点以及注意的问题(转)
- web项目在iis配置好后不能正确访问问题集锦,以及IIS常规设置
- Android清理webview缓存