ChenYilong / iOS11AdaptationTips

for iOS11 in [ObjC, Swift, English, 中文] {...} -- iOS11适配系列教程
MIT License
486 stars 47 forks source link

wkwebView加载mainBundle资源相关本地html 涉及html,css ,js等资源时奔溃 #7

Open relaxstis opened 7 years ago

relaxstis commented 7 years ago

This problem is based on iOS11 beta,the details are:

the request:

NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"html"];
NSMutableURLRequest * request = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:htmlPath]];
[self.webView loadRequest:request];

pragma mark - WKNavigationDelegate:

-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ 
    decisionHandler(WKNavigationActionPolicyAllow);//奔溃地方 (crash)
}

 -(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    decisionHandler(WKNavigationResponsePolicyAllow);
}

情况说明:前面使用了loadRequest的请求方式,奔溃的地方在后面的代理decidePolicyForNavigationAction:使用WKNavigationActionPolicyAllow奔溃;在iOS11 beta以下正常.

经调试:采用loadHtmlWithString时不调用baseurl不会奔溃,但是肯定没有使用和加载数据

奔溃信息:Thread 1: signal SIGABRT

invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.

libc++abi.dylib: terminate_handler unexpectedly threw an exception

Ask for your advice, thank you!!

NikoXu commented 6 years ago

我们在这里遇到的crash是正常请求远程服务端资源, 在decidePolicyForNavigationAction代理方法里处理navigationAction.navigationType以及URL scheme来决定WKNavigationActionPolicy,crash信息如下

invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
JoakimLiu commented 6 years ago

@sunTie 你项目里面有用到 WKWebViewJavascriptBridge 么?如果有的话,请参考

https://github.com/marcuswestin/WebViewJavascriptBridge/issues/278

decisionHandler(WKNavigationActionPolicyCancel);下面加上return; 我这边按照这个解决方案处理好了。

- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    if (webView != _webView) { return; }
    NSURL *url = navigationAction.request.URL;
    __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;

    if ([_base isCorrectProcotocolScheme:url]) {
        if ([_base isBridgeLoadedURL:url]) {
            [_base injectJavascriptFile];
        } else if ([_base isQueueMessageURL:url]) {
            [self WKFlushMessageQueue];
        } else {
            [_base logUnkownMessage:url];
        }
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }

    if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
        [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}