Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completion handler passed to -[WKPrivateNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once #278

Closed
lianweiqin opened this issue Apr 7, 2017 · 15 comments

Comments

@lianweiqin
Copy link

lianweiqin commented Apr 7, 2017

- (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);     //  executed**
    }
    
    if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
        **[_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];          //  executed** 
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}

I implement the selector @selector(webView:decidePolicyForNavigationAction:decisionHandler:)
and execute "decisionHandler(WKNavigationActionPolicyAllow);"

It seems the decisionHandler can be called twice and cause the crash.
No such thing has happened before...

@lokimeyburg
Copy link
Collaborator

(I updated your issue to make your code render in Markdown... makes it easier to read)

Your conditionals allow for more than one handler to be called. Perhaps try and make the statements mutually exclusive?

    if ([_base isCorrectProcotocolScheme:url]) {
       // ...
        decisionHandler(WKNavigationActionPolicyCancel);
    } else if (strongDelegate && ... ) {
        [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }

@yudun1989
Copy link

same issue. I met this problem on iOS 11 devices.

@rollingstoneW
Copy link

rollingstoneW commented Jul 31, 2017

image

It should be this?

@wunshine
Copy link

wunshine commented Aug 1, 2017

got the same problem and not fix yet

@ifwrite
Copy link

ifwrite commented Aug 2, 2017

add return; . under decisionHandler(WKNavigationActionPolicyCancel);

@iPermanent
Copy link

  • (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];
    }
    I disabled this code first
    //decisionHandler(WKNavigationActionPolicyCancel);
    }

    if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
    //Here you need to add some code judge if it's the nav by jsbridge then cancel it,
    if ([[URL.absoluteString lowercaseString] hasPrefix:@"https://wvjb_queue_message/"] || [[URL.absoluteString lowercaseString] hasPrefix:@"wvjbscheme://"]) {
    decisionHandler(WKNavigationActionPolicyCancel);
    }else{
    decisionHandler(WKNavigationActionPolicyAllow);
    }
    the code upon is my way to deal it. Hope can help you fix this problem
    [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler]; // executed**
    } else {
    decisionHandler(WKNavigationActionPolicyAllow);
    }
    }

@iPermanent
Copy link

the code need to be added in your own delegate, and delete the cancel action decisionHandler(WKNavigationActionPolicyCancel); in WKWebViewJavascriptBridge.m

pilot34 added a commit to pilot34/WebViewJavascriptBridge that referenced this issue Oct 24, 2017
@pilot34
Copy link

pilot34 commented Oct 24, 2017

Hm, why this issue is closed? I think, it is not fixed in the last version.

@iPermanent
Copy link

I think it's duplicate with the others, the same issues has exist already. It's not fixed at all.

@iosfighterlb
Copy link

Adding 'return'. Can't solve the problem on me.

It seems some sutiation it doesn't enter : “ if ([_base isWebViewJavascriptBridgeURL:url]) ”
For example , if you only use WKWebView.

i fix this bug with adding these code in Delegate method:

    WebViewJavascriptBridgeBase *base = [[WebViewJavascriptBridgeBase alloc] init];
    if ([base isWebViewJavascriptBridgeURL:navigationAction.request.URL])
    {
        return;
    }  // Add this IF statement in my project,  don`t need modify WebViewJavascriptBridge`s source code.
       // fixd 'Completion handler passed to -[WKWebViewJavascriptBridge webView:decidePolicyForNavigationAction:...
    decisionHandler(WKNavigationActionPolicyAllow);

With these, you can compulsively enter IF and execute return .

@marcuswestin
Copy link
Owner

Fixed in latest release (6.0.3)

@Dandre126
Copy link

  • (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
    {
    if (webView != _webView) {
    return;
    }
    NSURL *url = navigationAction.request.URL;
    if ([navigationAction.request.URL.scheme.lowercaseString isEqualToString:@"pingchang"]) {
    if (![self.jsHelper shouldLoadURLRequestWithURL:navigationAction.request.URL]) {
    decisionHandler(WKNavigationActionPolicyCancel);
    return; // iOS11或xcode9中,此处必须要加一个return,否则就会报上述错误。加了return就可以解决。
    }
    }else if ([url.scheme.lowercaseString isEqualToString:@"http"] ||
    [url.scheme.lowercaseString isEqualToString:@"https"]) {
    _seTipLabel.text = [NSString stringWithFormat:@"此内容由 %@ 提供",url.host];
    }

    decisionHandler(WKNavigationActionPolicyAllow);
    }

@housenkui
Copy link

yyy

Xcode 8.2 gave me an error if i use Iphone, but if i use Simulator that is ok.

what should i do?

If i user Xcode 9.2 that do well both in Iphone and Simulator.

@iPermanent
Copy link

You should declare an interface by protocol at the .h file, so the xcode can recognize this. And by the way, we always use the latest version Xcode to avoid strange problems on iOS, I recommend you to do it as well.

@Prathapreddy26
Copy link

What is the purpose of this method?

  • (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler;
    ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests