About communication between JavaScript and native code in WKWebView

WKWebView is a replacement of UIWebView that is available since iOS 2.0. Apple encourages using WKWebView instead of UIWebView in its documentation:

Note

In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView.

One of the key advantages of the new component is the more comfortable way to call native functions directly from JavaScript and to execute JavaScript functions at the native side. However, there are some limitations, which one should know:

  • WKWebView runs in its own process. On one hand it is a great performance improvement. On the on the hand it implies some unpleasant limitations in exchanging data between native app and the WKWebView
  • Native <=> JavaScript communication can only be asynchronous.
  • Native functions called from JavaScript cannot return values immediately.
  • The only way to return a value is to call another JavaScript function from native function with return value as parameter.
  • JavaScript functions can be called within native native methods only in global context.

To my opinion, limitations mentioned above are a step back comparing with UIWebView. With UIWebView it is possible to obtain JavaScript context and inject native(!) objects into that context by means of JSExport interface. There is then no difference wether you call a function on an injected object or some other JS function. Native functions can return values synchronously! The only disadvantage of this approach is that Apple has not exposed JavaScript context of the UIWebView officially. It is only possible to obtain the context  via private properties. That’s why this approach should not be used in product apps.