Fork us on GitHub

WKWebView

More powerful, faster but tricky browser on iOS
WKWebView

WKWebView

I’m assuming most of you didn’t write native iOS apps in the past. In this post I’ll discuss some things that are specific to iOS but I’ll try to explain them in laymen terms possibly oversimplifying some of the ideas. If you use HTML in your apps you should probably read this…​

One of the most important features in a modern app is the ability to show HTML using the native browser. It allows us to show things such as help screens, licenses etc. It lets us render some features e.g. our Crisp support is based on a BrowserComponent because that’s how their native library works.

It’s important that we use the native OS HTML renderer as we can’t JIT JavaScript on iOS (it’s prohibited) but the native HTML renderer can do that. So it’s much faster than anything we can build. It also lets us keep the app size manageable.

When we launched Codename One there was just one way to show HTML in iOS: UIWebView. It worked well for our needs and still works OK. A few years back (iOS 8) Apple introduced WKWebView which is faster. UIWebView runs within your app while WKWebView runs in its own process space and is embedded into your app. That means WKWebView can use "risky" optimizations without concern that a malicious app will abuse them.

So WKWebView is faster and more secure. To settle this further Apple deprecated UIWebView effectively signaling that we need to move to WKWebView.

The Problem

WKWebView is very different architecturally. Things like file URL’s might not work. Browser security restrictions such as CORS would be enforced more strictly and other such regressions might exist.

So we want to give you a way to go back and forth between WKWebView and UIWebView even on an individual BrowserComponent level.

Right now the default is still UIWebView but if Apple moves forward with eliminating UIWebView we might have no choice but to remove it or flip the default to WKWebView.

Using WKWebView

You can enable WKWebView by setting the display property 'BrowserComponent.useWKWebView' to 'true' e.g.:

Display.getInstace().setProperty("BrowserComponent.useWKWebView", "true");

All browser components created while this property is set to 'true' will use WKWebView on iOS. E.g.

BrowserComponent bc1 = new BrowserComponent();
Display.getInstance().setProperty("BrowserComponent.useWKWebView", "true");
BrowserComponent bc2 = new BrowserComponent();
Display.getInstance().setProperty("BrowserComponent.useWKWebView", "false");
BrowserComponent bc3 = new BrowserComponent();

In this example, bc1 and bc3 will use UIWebView on iOS, and bc2 will use WKWebView. In the future we may change the default, which would mean that bc1 would also use WKWebView.

We had to use a Display property as the client property might be set after the BrowserComponent peer was created

Another important bit is that WKWebView requires us to link the WebKit.framework. This will only happen if the ios.useWKWebView build hint is set to true. We automatically add this build hint in the simulator if you create any BrowserComponent while the BrowserComponent.useWKWebView property is true. Naturally you will need to run this in the simulator for this to work. The code should fall back to UIWebView if you fail to do this.

Notice that this feature is still experimental at this time.

Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.