WKWebView - Issues with JavaScript interface

Hello,

I am currently investigating the possiblity of migrating our OSX Mac App to use WKWebView rather than the old WebView. We have been having some performance problems with WebView and WKWebView looks much better in that regard.


My problem is that the web-content I host in the WebView is heavily reliant on the JavaScript interface - both for calls from Native Objective C and for calls from JS back to Native.


Now I can see that the API to call from Native --> JS has changed slightly - the synchronous call to

stringByEvaluatingJavaScriptFromString(...)

is now an asynchronous call in WKWebView:

evaluateJavaScript(string, callbackHandler)

That part is OK, I can most likely work around this!

However, the API's for calls in the opposite direction seem to be completely different or even non-existant? It looks like it's possibly unworkable for me, or certainly will involve a lot of rework, both in my native App and in the hosted web (JS) code.

In our existing App, I am able to call into Objective-C functions directly from JavaScript and synchronously return results back to the JS code. We do this by implementing the windowScriptObjectAvailable delegate function defined in WebView's WebFrameLoadDelegate and "registering" objects that the JavaScript code can access, e.g.:


- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
{
    [windowScriptObject setValue:JSAccessibleObj forKey:@"JSAccessibleObj"];
}

And then from JS, I can do something like this to call a native method on the JSAccessibleObj object directly:

var s = window.JSAccessibleObj.foo();

So now I'm looking at the WKWebView to see if a similar approach is available and it looks like it's not? WKWebView does not adhere to the WebFrameLoadDelegate delegate and therefore doesn't have the windowScriptObjectAvailable delegate function or anything closely resembling it. Does WKWebView have the concept of windowScriptObject at all?

From digging around, I did find that calling from JS back into the Native is somewhat possible by implementing the delegate WKScriptMessageHandler and then implementing this function:


- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
   NSDictionary *sentData = (NSDictionary*)message.body;
...
}

This does work, but really, it's not what I'm looking for. This mechanism will only allow me pass JSON style message blobs from JS to Native. Perhaps, from the didReceiveScriptMessage(...) function I can then parse that message and call the appropriate native function. That might be workable if the JS isn't reliant on getting a result back from the native (a fire and forget call) but in many cases, I do want the result, i.e. in the JS I want this:

var s = window.JSAccessibleObj.foo();

Is there even the concept of a "callback" mechanism, where JS gives me a function I can call back into when I have the result ready on the native side? Right now, the only way I can see this working is something like this:

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
   NSDictionary *sentData = (NSDictionary*)message.body;

   //1. parse the message and determine which Native function to call and get the result

   //2. Call back to Javacript with the "result" obtained in step 1
   wkwebview.evaluateJavaScript(....)
...
}

This is far from ideal, as it means (assuming it's workable) that I'd have to do major surgery in my current JS <----> Native interface.

I'd appreciate any pointers on the best approach for this problem.

Thanks

Joe.

I also have this question .now I want to use WKWebview replace UIWebview on the situation that not change js code only change the native code.what can I do.thanks.

Dear Joe - Did you find answer for this. Could you please help me how did you solve this issue. I have not found anything on internet for this problem. Thank you for your help in-advance.
WKWebView - Issues with JavaScript interface
 
 
Q