Window.open() is not working in WKWebView

7.7k Views Asked by At

I am trying to open a URL in safari browser while clicking it from app's iOS WKWebView, but when I call window.open() from javascript which has no effects.

It's not hitting the decide policy in WKWebView,

[Foundation.Export("webViewecidePolicyForNavigationActionecisionHandler:")]
public void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)

I have tried to override WKUIDelegate method, but it's not working. :(

Could anyone help me out?

3

There are 3 best solutions below

0
On
  • Since method DecidePolicy is contained inside the IWKNavigationDelegate , so you should implement it not WKUIDelegate.

  • The method string inside Export is incomplete , it should be [Export("webView:decidePolicyForNavigationAction:decisionHandler:")]

There are two ways you can implement the delegate.

Strong Delegate:

public override void ViewDidLoad()
{
    base.ViewDidLoad();
    WKWebView webview = new WKWebView(this.View.Bounds,null);
    webview.NavigationDelegate = new MyWKNavigationDelegate();
}

class MyWKNavigationDelegate : WKNavigationDelegate
{
    public override void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)
    {           
    }
}

Weak Delegate:

public override void ViewDidLoad()
{
    base.ViewDidLoad();
    WKWebView webview = new WKWebView(this.View.Bounds,null);
    webview.WeakNavigationDelegate = this;
}

[Export("webView:decidePolicyForNavigationAction:decisionHandler:")]
public  void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction,  Action<WKNavigationActionPolicy> decisionHandler)
{
}
0
On

Note - I don't have xamarin experience but I know how "window.open()" js works in WKWebView with native code so I hope this answer will help you connect the missing dots.

First, set UIDelegate where you configure your web view.. (in viewDidLoad in your case)

webView.uiDelegate = self

Second, implement this protocol method of UIDelegate. The idea is to create a web view on fly and a view controller on the fly and present/push it and return this web view instance to WebKit so it can establish the linkage with parent web view and load the url (first parameter of window.open call).

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        let childWebView = WKWebView(frame: .zero, configuration: configuration)   // Must use the configuration provided by this method
        let webViewController = ViewController() // create an instance of a new view controller that you want to push or present with a web view
        webViewController.webView = childWebView // provide this new child web view to view controller for layout purpose 
        navigationController?.pushViewController(webViewController, animated: true)
        return childWebView
}
0
On

Here https://developer.apple.com/forums/thread/664267 is advice to set WKPreferences.javaScriptCanOpenWindowsAutomatically = true but it is not working. iOS is pain. Everything what works on Android is problematic on iOS. Android WebView has no problem with window.open(). We needed to open link with PDF and link is dynamically created. We had to change "button" element with onclick="window.open(...)" to "a" element with target=_blank and dynamic href=...