iOS11 WKWebView问题汇总
问题一描述:
iOS9和iOS10用WKWebView加载URL都没有问题,iOS11却是一片空白
可能是用了NSMutableURLRequest,iOS11貌似不支持NSMutableURLRequest,无论是用UIWebView还是WKWebView,都不支持NSMutableURLRequest
解决方法参考
if#available(iOS11,*){ letrequest=NSURLRequest.init(url:URL.init(string:urlStr)!) self.wkWebView.load(requestasURLRequest) }else{ letrequest=NSMutableURLRequest.init(url:URL.init(string:urlStr)!,cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData,timeoutInterval:60) request.httpMethod="GET" request.httpBody=("token="+tokenValue()).data(using:String.Encoding.utf8) self.wkWebView.load(requestasURLRequest) }
问题二描述:在用iPhoneX的模拟器进入Hybrid项目时,发现一进去就崩溃,崩溃信息少的可怜:
libc++abi.dylib:terminatingwithuncaughtexceptionoftypeNSException
靠这玩意儿肯定是定位不出bug的,不过全局断点还是给出了一点信息:
-(void)webView:(WKWebView*)webViewdecidePolicyForNavigationAction:(WKNavigationAction*)navigationActiondecisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler{ NSString*requestString=navigationAction.request.URL.absoluteString; //对外链、拨号和跳转appstore做特殊处理 UIApplication*app=[UIApplicationsharedApplication]; NSURL*url=[navigationAction.requestURL]; //电话 //此处省略若干业务代码 if([url.absoluteStringcontainsString:@"itunes.apple.com"]) { if([appcanOpenURL:url]) { [appopenURL:url]; decisionHandler(WKNavigationActionPolicyCancel); } } if([requestStringhasPrefix:@"easy-js:"]){ [selfhandleRequestString:requestStringwebView:(EasyJSWebView*)webView.superview]; decisionHandler(WKNavigationActionPolicyCancel); } if([self.realDelegaterespondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) { [self.realDelegatewebView:webViewdecidePolicyForNavigationAction:navigationActiondecisionHandler:decisionHandler]; } decisionHandler(WKNavigationActionPolicyAllow);//崩在这里 }
仍然不知道为啥子崩在这儿?之前一直是没问题的啊??
小Tips:
为了获取一些堆栈信息以便于快准狠的定位问题,可以在main函数里:
intmain(intargc,char*argv[]){ @try{ @autoreleasepool { returnUIApplicationMain(argc,argv,nil,NSStringFromClass([AppDelegateclass])); } } @catch(NSException*exception) { NSDebugLog(@"Exception=%@\nStackTrace:%@",exception,[exceptioncallStackSymbols]); } }
最终得到一条关键报错:
Completionhandlerpassedto-[WKPrivateNavigationDelegatewebView:decidePolicyForNavigationAction:decisionHandler:]wascalledmorethanonce
意思就是WKWebView的这个代理方法被多次调用了。
if([requestStringhasPrefix:@"easy-js:"]){ [selfhandleRequestString:requestStringwebView:(EasyJSWebView*)webView.superview]; decisionHandler(WKNavigationActionPolicyCancel); } if([self.realDelegaterespondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) { [self.realDelegatewebView:webViewdecidePolicyForNavigationAction:navigationActiondecisionHandler:decisionHandler]; } decisionHandler(WKNavigationActionPolicyAllow);//崩在这里
简单分析一下被多次调用的原因:
1、系统判断这个方法被多次执行,主要是看decisionHandler()是否被多次执行;
2、由于if判断里会执行decisionHandler(),最后一行代码也会执行decisionHandler(),并且self.realDelegate中也会执行decisionHandler(),这就导致了decisionHandler()这个handler可能会被多次执行。
那解决问题的方向就是修改代码保证WKWebView单次LoadRequest只调一次此代理方法~
修改如下:
if([requestStringhasPrefix:@"easy-js:"]){ [selfhandleRequestString:requestStringwebView:(EasyJSWebView*)webView.superview]; decisionHandler(WKNavigationActionPolicyCancel); } elseif([self.realDelegaterespondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) { [self.realDelegatewebView:webViewdecidePolicyForNavigationAction:navigationActiondecisionHandler:decisionHandler]; }else{ decisionHandler(WKNavigationActionPolicyAllow); }
即保证了单次LoadRequest只执行一次decisionHandler()
问题三描述:iOS11WKWebview获取高度不准确
遇见这个问题的时候,我发现偏离了大概64像素,由此联想到了tableView和collectionView。
故解决办法如下:
if(@available(iOS11.0,*)){ _webView.scrollView.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNever; _webView.scrollView.contentInset=UIEdgeInsetsMake(0,0,0,0); _webView.scrollView.scrollIndicatorInsets=_webView.scrollView.contentInset; }