1
votes

WKWebview and Phonegap Build: Is communication between index.js and WKWebView even possible?

I'm using Phonegap Build to generate my mobile device executables. I'm opening a webview and loading a page off our website. While using UIWebView I had no problem coding index.js on the mobile device to listen for a loadstop event and call executescript to execute javascript on the web page in the webview and return the results to index.js where I could do whatever I needed.

But UIWebView is dog-slow, so for iOS I've been trying to get WKWebView to work via the cordova-plugin-wkwebview-engine plug-in.

I can get the WKWebview to open my URL, and it is blazing fast compared to UIWebView, but after days of searching (every page containing 'WKWebView' and 'Phonegap' that Google knows of) and experimentation I have been unable to find any way to detect loadstop (or equivalent), nor have I found any way to execute a script in WKWebView from index.js.

I would probably be happy with ANY method to communicate between index.js and WKWebView. Is there a process similar to executescript after loadstop event, even if it is async? Is there some type of messaging capability?

I'd love to see some code examples for index.js.

I'm beginning to think that I'm going to have to break down and resort to learning native code in xcode to make this happen. I sure hope not because Phonegap Build has worked fine for me thus far.

Has anyone had any luck with this?

Here is the code that works under UIWebView. It works well enough under WKWebView to open the URL, but loadstop does not trigger and there is no execution of the script.


launchBrowserWindow: function (url) { 
    var ref;
    try {
        ref = window.open(url, '_self', 'location=no,toolbar=no');                
    } catch (e) {
        console.log("McMApp catch window.open fail: " + url + " err: " + e.message);
    }
    try {
        ref.addEventListener("loadstop", function () {
            ref.executeScript(
                { code: 'window.location.search' },
                function (value) {
                    var requestString = value[0];
                    console.log("McMApp loadstop request string: " + requestString);
                });

        });
    } catch (e) {
        console.log("McMApp FAIL ref.addeventlistener loadstop");
    }
},

50 hard-boiled eggs to anyone that can help me get this working.

1

1 Answers

0
votes

InAppBrowser is a fickle beast, so happy to help! For reference, I have an app now that uses InAppBrowser and WKWebView and both work using the following:

"LoadStop" not firing:

  1. Self vs _blank: I typically open the Browser via "_blank" instead of "self". Try that.
  2. Newer versions of InAppBrowser should still be automatically aliased to 'window.open' but in the docs they mention this will go away soon. You can do that in the deviceready event like so:

    window.open = cordova.InAppBrowser.open;

Or, and probably the safer option, just use "cordova.InAppBrowser.open".

Here's code I use. Try printing out or "alert"-ing the URLs that are coming through. They may not be what you expect, especially if there are multiple redirects.

var inAppBrowserRef = cordova.InAppBrowser.open("www.google.com", '_blank', 'location=no,toolbar=yes');
        inAppBrowserRef.addEventListener('loadstop', function(event) {
            console.log("loadstop: " + event.url);
            alert("loadstop: " + event.url);

            // run execute script code
            }
        });

Also, make sure any use of InAppBrowser is within/after the 'deviceready' event fires.

Execute Script Issue

I believe here the problem is that your code isn't firing. See here, wrap it into a function and call it immediately:

ref.executeScript(
                { code: 'var runCode = function() { window.location.search; } runCode();' },
                function (value) {
                    var requestString = value[0];
                    console.log("McMApp loadstop request string: " + requestString);
                });

I'm not totally sure, but according to MDN, shouldn't you be passing a parameter to the location search function too?

// Append "someData" as url parameter query
window.location.search = "someData";

Last, note that WKWebView does have lots of known issues currently. Always check first for known issues on GitHub or official Apache Cordova site, etc, because as you wrote, you can burn many hours getting nowhere. I'm currently using this fork of the WKWebView - this team is moving much faster than the "official" plugin fixing bugs so you might try that.