Skip to content

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

Closed
@lianweiqin

Description

@lianweiqin
- (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...

Activity

lokimeyburg

lokimeyburg commented on Apr 12, 2017

@lokimeyburg
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

yudun1989 commented on Jul 31, 2017

@yudun1989

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

rollingstoneW

rollingstoneW commented on Jul 31, 2017

@rollingstoneW

image

It should be this?

wunshine

wunshine commented on Aug 1, 2017

@wunshine

got the same problem and not fix yet

swifterfit

swifterfit commented on Aug 2, 2017

@swifterfit

add return; . under decisionHandler(WKNavigationActionPolicyCancel);

iPermanent

iPermanent commented on Oct 20, 2017

@iPermanent
  • (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

iPermanent commented on Oct 20, 2017

@iPermanent

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

added a commit that references this issue on Oct 24, 2017
pilot34

pilot34 commented on Oct 24, 2017

@pilot34

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

iPermanent

iPermanent commented on Oct 24, 2017

@iPermanent

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

iosfighterlb

iosfighterlb commented on Nov 6, 2017

@iosfighterlb

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

marcuswestin commented on Nov 8, 2017

@marcuswestin
Owner

Fixed in latest release (6.0.3)

Dandre126

Dandre126 commented on Nov 27, 2017

@Dandre126
  • (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

housenkui commented on Mar 20, 2018

@housenkui

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

iPermanent commented on Mar 20, 2018

@iPermanent

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

Prathapreddy26 commented on Jan 8, 2019

@Prathapreddy26

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @lokimeyburg@marcuswestin@yudun1989@pilot34@iPermanent

        Issue actions

          Completion handler passed to -[WKPrivateNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once · Issue #278 · marcuswestin/WebViewJavascriptBridge