JavaScript not executed in WKWebView

Since I'm going a little crazy about this, I decided to give him another try and report it here.

So...

I have a simple Swift / Cocoa application with WKWebView in it.

I upload a local HTML file (which, along with the rest of the dependencies .css / .js, is copied to the package inside the /web folder).

Here is the full code:

 <!DOCTYPE html> <html> <head> <title>IBAN Validator</title> <meta name="viewport" content="width=device-width"/> <meta charset="UTF-8"> <link href="style/font-awesome.min.css" type="text/css" rel="stylesheet"/> <link href="style/electriq.css" type="text/css" rel="stylesheet"/> <link href="style/custom.css" type="text/css" rel="stylesheet" /> </head> <body> <!-- window/ --> <div class="window"> <div class="content" style="text-align: center"> <div class="panel"> <input id="iban" type="text" style="text-align:center;"><br/> <div style="position: relative; max-width: 150px; width: 100%; margin: 0 auto"> <a id="validateButton" href="#" class="button" style="width:150px;">Validate</a> <span id="resultValid" style="position:absolute; left: calc(100% + 20px); top: 10%; color: green; font-size: 20px; display:none;"><i class="fa fa-check"></i></span> <span id="resultInvalid" style="position:absolute; left: calc(100% + 20px); top: 10%; color: red; font-size: 20px; display:none;"><i class="fa fa-close"></i></span> </div> </div> </div> </div> <!-- /window --> <div id="loader_overlay" style="padding-top:10%"> <i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i><br/> </div> <!-- scripts/ --> <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script> <script src="jquery.min.js" type="text/javascript"></script> <script> if (typeof window.jQuery !== 'undefined') { window.document.getElementById("loader_overlay").innerHTML += "."; } else { window.document.getElementById("loader_overlay").innerHTML += "x"; } </script> <script src="handlebars.min.js" type="text/javascript"></script> <script> if (typeof window.Handlebars !== 'undefined') { window.document.getElementById("loader_overlay").innerHTML += "."; } else { window.document.getElementById("loader_overlay").innerHTML += "x"; } </script> <script src="bridgecommander.js" type="text/javascript"></script> <script> if (typeof window.BridgeCommander !== 'undefined') { window.document.getElementById("loader_overlay").innerHTML += "."; } else { window.document.getElementById("loader_overlay").innerHTML += "x"; } </script> <script src="iban.js" type="text/javascript"></script> <script> if (typeof window.IBAN !== 'undefined') { window.document.getElementById("loader_overlay").innerHTML += "."; } else { window.document.getElementById("loader_overlay").innerHTML += "x"; } </script> <!-- <script src="app.js" type="text/javascript"></script> --> <script> // Generated by CoffeeScript 2.0.2 var doValidate; window.appLoaded = true; window.document.getElementById("loader_overlay").innerHTML += "."; BridgeCommander.call("echo", "Before: onload"); window.document.getElementById("loader_overlay").innerHTML += "."; window.onload = function() { BridgeCommander.call("echo", "Inside: onload"); document.getElementById("loader_overlay").style.display = 'none'; return $("#validateButton").on("click", doValidate); }; window.document.getElementById("loader_overlay").innerHTML += "."; BridgeCommander.call("echo", "After: onload"); doValidate = function() { var iban, valid; iban = $("#iban").val(); valid = IBAN.isValid(iban); if (valid) { $("#resultValid").show(); $("#resultInvalid").hide(); $("#validateButton").removeClass("invalid").addClass("valid"); BridgeCommander.call("echo", `Validating: ${iban}, Result: valid`); } else { $("#resultValid").hide(); $("#resultInvalid").show(); $("#validateButton").removeClass("valid").addClass("invalid"); BridgeCommander.call("echo", `Validating: ${iban}, Result: invalid`); } setTimeout(function() { $("#validateButton").removeClass("valid").removeClass("invalid"); $("#resultValid").hide(); return $("#resultInvalid").hide(); }, 3000); return false; }; window.document.getElementById("loader_overlay").innerHTML += "."; if (typeof window.appLoaded !== 'undefined') { window.document.getElementById("loader_overlay").innerHTML += "."; } else { window.document.getElementById("loader_overlay").innerHTML += "x"; } </script> <script>if (window.module) module = window.module;</script> <!-- /scripts --> </body> </html> 

Important note: Here (value on my Mac - and all Macs since 10.3.1 I tried this) everything works fine. When I upload the same binary to the App Store for viewing, I continue to receive the same โ€œscreenshotโ€ of the error, meaning that none of the code in my last <script></script> block is executed. (after the window.appLoaded = true ).


What could be? I literally tried to debug something (hence the numerous window.document.getElementById thing, adding dots to make sure everything works), but still nothing.

As you can see, I am loading a few scripts (which, according to my tests, load normally), and I also have some snippets of embedded JS code (which still works fine). Except for the last one! (which, in spite of everything, even from an external file, seems to refuse to load ...)

Again, I thought that I was cached, I donโ€™t know, but I remind you that it seems to work everywhere except for the machine of the Review: S command

Any idea would be welcome!


PS If something is unclear, please feel free to ask me something.


Update: (11/28/2017) Tried it all with a simple old style - WebView (in case it is related to WKWebView ), and yet my application is rejected. Or, more precisely, my application (the exact version, the same thing) works fine everywhere except for the guy who views it.

+7
javascript cocoa swift webview macos
source share
1 answer

This may be because the browser does not know how to parse the contents of script tags

Tags

<script></script> require a type attribute for them, so most browsers will consider it the same as the last, but since none of your code containing script tags indicates how it can parse a script supports more than javascript, like VBScript , when you open <script> for javascript, it should be <script type="text/javascript">

Another problem might be window.onload I would recommend that you change it to a DOMContentLoaded event and use closure to make sure that it is executing the code.

Moreover, why don't you load jQuery in the header tag where it should be loaded, move <script src="jquery.min.js" type="text/javascript"></script> inside <head></head> .

Following this, if you have jQuery, why are you mixing jQuery and pure Javascript, if you have jQuery, use its smaller code and cleaner

  (function($){ $(function(){ window.appLoaded = true; $("loader_overlay").append("."); BridgeCommander.call("echo", "Before: onload"); $("loader_overlay").append("."); $("loader_overlay").append("."); BridgeCommander.call("echo", "After: onload"); function doValidate() { var iban, valid; iban = $("#iban").val(); valid = IBAN.isValid(iban); if (valid) { $("#resultValid").show(); $("#resultInvalid").hide(); $("#validateButton").removeClass("invalid") .addClass("valid"); BridgeCommander.call("echo", `Validating: ${iban}, Result: valid`); } else { $("#resultValid").hide(); $("#resultInvalid").show(); $("#validateButton").removeClass("valid") .addClass("invalid"); BridgeCommander.call("echo", `Validating: ${iban}, Result: invalid`); } setTimeout(function() { $("#validateButton").removeClass("valid") .removeClass("invalid"); $("#resultValid").hide(); return $("#resultInvalid").hide(); }, 3000); return false; }; (function(doValidate) { BridgeCommander.call("echo", "Inside: onload"); $("loader_overlay").css("display",'none'); return $("#validateButton").on("click", doValidate); })(doValidate); window.document.getElementById("loader_overlay").innerHTML += "."; if (typeof window.appLoaded !== 'undefined') { window.document.getElementById("loader_overlay").innerHTML += "."; } else { window.document.getElementById("loader_overlay").innerHTML += "x"; } if (window.module){ module = window.module; } }); }); 

In another note, please get rid of all file upload checks. therefore all of the following code blocks

 if (typeof window.Handlebars !== 'undefined') { window.document.getElementById("loader_overlay").innerHTML += "."; } else { window.document.getElementById("loader_overlay").innerHTML += "x"; } 

They are only needed for debugging, and you know that this is a Web Kit, if the file is downloaded to one, which is downloaded at all. therefore, you do not need this check, they just use the processing power of the phone and add work to your application for no good reason. except to put a. in the overlay ...

and again all <script src=... should be inside the <head> tags, in this case all your code should be inside the script tags and use jQuery, as my version does.

How do you test this application on Mac, do you use iPhone emulator? or a real iPhone for testing, I will always recommend the latter. and you tested on one of them, because you don't seem to say that you have, if you donโ€™t get the device registered for testing in your developer account, create keys for testing and building the test version, and then use the debugging tools with Safari or Chrome on WebView and make sure it all works.

0
source share

All Articles