0

This post and this post addresses the problem of using JavaScript to open WKWebView links in mobile Safari, but for some reason, the solutions provided don't work.

The code below incorporates elements of different solutions, yet still the link does not open after clicking the button.

In fact, webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) and userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) don't even get called.

HTML:

<html>
    <style type="text/css">
        #button { width: 100px; height: 50px; background: red; }
    </style>

    <div id="button">CLICK TO GO</div>

    <script type="text/javascript">

    var button = document.getElementById("button");
    button.addEventListener("click", doTest);

    function doTest() {
        window.open("http://www.google.com", target="_blank");
        button.innerHTML = "HEY";
    }

    </script>
</html>

ViewController:

class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate {

    var webView: WKWebView?
    let webViewContentController = WKUserContentController()

    override func viewDidLoad() {
        super.viewDidLoad()

        let config = WKWebViewConfiguration()
        config.userContentController = webViewContentController

        webView = WKWebView(frame: view.bounds, configuration: config)

        webView!.navigationDelegate = self
        webView!.uiDelegate = self  //must have this

        var fileURL = URL(fileURLWithPath: Bundle.main.path(forResource:"Mooncake.html", ofType: nil)!)
        webView!.loadFileURL(fileURL, allowingReadAccessTo: fileURL)

        view.addSubview(webView!)
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    }

    // this handles target=_blank links by opening them in the same view
    func webView(webView: WKWebView!, createWebViewWithConfiguration configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView! {
        if navigationAction.targetFrame == nil {
            let url = navigationAction.request.url!
            let urlString = url.description.lowercased()

            if urlString.contains("http://") || urlString.contains("https://") || urlString.contains("mailto:") {
                UIApplication.shared.openURL(url)
            }
        }
        return nil
    }

    func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
    }
}
Community
  • 1
  • 1
Crashalot
  • 33,605
  • 61
  • 269
  • 439

1 Answers1

0

The problem was using outdated function definitions, lifted from the SO answers, for

webView(webView: WKWebView!, createWebViewWithConfiguration configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView!

and

webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void)

Using the Swift 3 function definitions as defined by the class docs solved the problem.

Crashalot
  • 33,605
  • 61
  • 269
  • 439