WKWebView使用遇到的问题
2017-10-03 10:30:40 # Objective-C

前言:

WKWebView在iOS8之后正式替代UIWebView,速度方面确实提升了不少。关于WKWebView的简单使用,在《聊一聊WKWebView》中我已经介绍过了,这里就不再絮叨,本篇主要记录s三个开发中遇到的问题。

1、去缓存问题

我们在第一次打开webView后,移动端为了使用的便捷,会在本地做一个缓存,服务器端也有类似的缓存。但有时服务器端更改信息或者web端更改界面信息。我们往往打开移动端的webView界面,仍然是原来的界面状态,这就是缓存机制造成的现象。
解决方法:如果不考虑流量,则需要在请求时忽略本地和远程的缓存即可,使用NSURLRequestReloadIgnoringLocalAndRemoteCacheData

1
2
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:20];
[self.webView loadRequest:request];

这里附上iOS提供的请求缓存类型:

1
2
3
4
5
6
7
8
9
10
typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
{
NSURLRequestUseProtocolCachePolicy = 0,
NSURLRequestReloadIgnoringLocalCacheData = 1,
NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
NSURLRequestReturnCacheDataElseLoad = 2,
NSURLRequestReturnCacheDataDontLoad = 3,
NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
};

也可以看看这篇文章:《iOS webview加载时序和缓存问题总结

2、拦截WKWebView中界面的URL,自己进行处理跳转(例如跳转到appstore、支付宝等)

如果在webView界面中有跳转appstore、支付宝等调手机中app的点击按钮时,如果iOS端不做处理的话,是调不起来手机中的app的。
我们需要做的就是在代理方法中截取webViewurl,再使用iOS的代码进行跳转。
例如打开appstore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSURL *url = navigationAction.request.URL;
UIApplication *app = [UIApplication sharedApplication];
// 打开appstore
if ([url.absoluteString containsString:@"https://itunes.apple.com/"]){
if ([app canOpenURL:url]){
[[UIApplication sharedApplication] openURL:url];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
decisionHandler(WKNavigationActionPolicyAllow);
}

4、在WKWebView中点击事件需要上传cookie中的数据,但cookie数据有问题

开发中发现,在WKWebView中点击获取验证码等失败(抓包工具查看,发现需要和请求一块上传cookie中的数据,实际并没有上传或者数据丢失一部分)

在WKWebView中,cookie的是需要我们自己去设置的,这一点和UIWebView不同。

1
2
3
4
-(void)setUIWebviewcookie{
NSHTTPCookieStorage *cs = [NSHTTPCookieStorage sharedHTTPCookieStorage];
[cs setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
}

在webView响应请求的代理方法中,查看cookie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
//读取wkwebview中的cookie 方法1
for (NSHTTPCookie *cookie in cookies) {
//[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
NSLog(@"wkwebview中的cookie:%@", cookie);
}
//读取wkwebview中的cookie 方法2 读取Set-Cookie字段
NSString *cookieString = [[response allHeaderFields] valueForKey:@"Set-Cookie"];
NSLog(@"wkwebview中的cookie:%@", cookieString);
//看看存入到了NSHTTPCookieStorage了没有
NSHTTPCookieStorage *cookieJar2 = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in cookieJar2.cookies) {
NSLog(@"NSHTTPCookieStorage中的cookie%@", cookie);
}
decisionHandler(WKNavigationResponsePolicyAllow);
}