[iOS] Handling popup/new window inside web view

Kent Winder
Nextzy
Published in
3 min readJun 5, 2018

Have you ever clicked some links inside your web view and nothing happens, or when you clicked login with social network button (Facebook, Google,…) and a white page appears out of nowhere? Because right now, web view does not support new windows like normal browsers. It’s when we have to handle it ourselves.

I create a simple web page here (with all of the above cases) for the demo project which you can find at the end of this article. Feel free to use it for your own testing project if you want to.

Solution 1: Using javascript injection

In this solution, every time the web view opens a web page (don’t forget to add WKNavigationDelegate for this web view), we will inject a javascript code block into that page to override window.open() function, so instead of opening a new window, it just loads that new url in that same window

webView.evaluateJavaScript("window.open = function(open) { return function (url, name, features) { window.location.href = url; return window; }; } (window.open);", completionHandler: nil)

We also need to inject a javascript code block to handle closing the dialog by using url scheme, so when the popup is closed the web view controller will be dismissed

webView.evaluateJavaScript("window.close = function() { window.location.href = 'myapp://closewebview'; }", completionHandler: nil)

The whole block of code should look like this

For <a href="http://a_hyper_link" target="_blank">Display name</a> we can use WKUIDelegate to load request of new window in that current window of web view

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if !(navigationAction.targetFrame?.isMainFrame ?? false) {
webView.load(navigationAction.request)
}
return nil
}

The downside of this solution is that you have to handle every javascript function which creates a new window inside web view. There is a better one, solution 2!

Solution 2: Adding sub view

With this solution, when we create the web view we must create from WKPreferences with javaScriptCanOpenWindowsAutomatically flag set to true, this will allow web page to open popup

Then every time this web view wants to create a new window, we create a popup web view for that window and add it to current view hierarchy

… so when user closes the popup, we just have to remove the popup web view

Demo project for solution 2 (which I find it better) can be found here: https://github.com/kentwinder/WebView-Optimization

--

--

Kent Winder
Nextzy
Editor for

Just a regular guy who loves coding, reading, and getting tattoos