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;
}