Q:

swift 3 WKWebView delegate WKNavigationDelegate Ambiguous method

I created a class named JSBridge, this class implements the WKNavigationDelegate, I did some custom stuff in the protocol method, and then call another UIViewController's default WKNavigationDelegate, for example WebViewController aka webViewDelegate, so I have to do like this 
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let webViewDelegate = webViewDelegate , self.webView == webView else {
        decisionHandler(.allow)
        return
    }

    //do something here then call `WebViewController`'s implementation
    if webViewDelegate.responds(to: #selector(webViewDelegate.webView(_:decidePolicyFor:decisionHandler:))) {
            webViewDelegate.webView!(webView, decidePolicyFor: navigationAction, decisionHandler: decisionHandler)
        } else {
            decisionHandler(.allow)
        }
}

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    guard let webViewDelegate = webViewDelegate , self.webView == webView else {
        decisionHandler(.allow)
        return
    }

    //do something here then 
    if webViewDelegate.responds(to: #selector(webViewDelegate.webView(_:decidePolicyFor:decisionHandler:))) {
        webViewDelegate.webView!(webView, decidePolicyFor: navigationResponse, decisionHandler: decisionHandler)
    } else {
        decisionHandler(.allow)
    }
}

my problem is in xcode8(swift3) the compiler gives me the error:
     Ambiguous use of 'webView(_:decidePolicyFor:decisionHandler:)', they have the same name to compiler
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void)
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)

A:

You can use as to choose one from some ambiguous methods:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let webViewDelegate = webViewDelegate , self.webView == webView else {
        decisionHandler(.allow)
        return
    }

    typealias WKNavigationActionMethodType = (WKWebView,WKNavigationAction,@escaping(WKNavigationActionPolicy)->Void) -> Void
    if webViewDelegate.responds(to: #selector(webView(_:decidePolicyFor:decisionHandler:) as WKNavigationActionMethodType)) {
        webViewDelegate.webView!(webView, decidePolicyFor: navigationAction, decisionHandler: decisionHandler)
    } else {
        decisionHandler(.allow)
    }
}

Another way to treat this sort of situation is "avoid using responds(to:) and use Optional chaining":
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let webViewDelegate = webViewDelegate , self.webView == webView else {
        decisionHandler(.allow)
        return
    }

    if webViewDelegate.webView?(webView, decidePolicyFor: navigationAction, decisionHandler: decisionHandler) == nil {
        decisionHandler(.allow)
    }
}

The delegate method's return type is Void, so its Optional chained result is of type Void?. In your case, it becomes nil only when the optional method is not implemented in the instance. So, comparing the result to nil is checking the optional method is implemented (and actually called) or not.

