1

I need to know when my GWT web application goes to the background on an iPad. The application is not a native iOS app, but rather has a "wrapper" around it allowing it to run as an app. The wrapper is written in Swift and uses the UIWebView.

The application needs to know when the home button is pressed in order to trigger some logic that if a user goes outside of the app then the app should display a warning screen upon returning to the app (i.e., receives focus). This logic should be true no matter how the app loses focus, unless they explicitly exit the app. I cannot explain why that functionality is necessary due to security purposes, but suffice to say this isn't a general audience type of application; there are specific scenarios under which this app is used.

I've tried using document.hasFocus(), but it always returns true, even though this same logic works on chromebooks, Windows machines, and macbooks.

I added visibilityChange listener, but the visibilityState is always visible. I also added event listeners for pageshow and pagehide. A debug console statement prints out for the pageshow eventlistener, but never for the pagehide eventlistener. Lastly, I added an event listener for the unload event, but I never see my console statement print out for it.

Based on various searches and articles I've read, it seems mobile Safari ignores most, if not all of these listeners, and the only option I haven't seem to have tried is using timers which I'd prefer to avoid. Also, I need an HTML/Javascript solution as I can only modify my application and cannnot modify the "wrapper" app. I'm using an iPad Pro with iOS 11.4.

Here's just one of the many articles that I referenced: How to detect in iOS webapp when switching back to Safari from background?

The relevant code from the application is below. Any thoughts or suggestions are greatly appreciated!

/*************************** page visibility ***************************/
var hidden, visibilityChange;
    if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
    hidden = "hidden";
    visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
    hidden = "msHidden";
    visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
    hidden = "webkitHidden";
    visibilityChange = "webkitvisibilitychange";
}

console.log("debug - common.js - customBlur - visibilityChange : " + visibilityChange + " | hidden: " + hidden);


if (typeof document.addEventListener === "undefined" || hidden === undefined) {
    console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
// Handle page visibility change
    document.addEventListener(visibilityChange, handleVisibilityChange, false);
}

var forceBlur = false;
function handleVisibilityChange() {
if (document.visibilityState == 'hidden') {
    console.log("debug - common.js - handleVisibilityChange - calling delayBlur");
    forceBlur = true;
} else console.log("debug - common.js - handleVisibilityChange - document not hidden");
}

/*************************** pageshow and pagehide ***************************/
var forcePhBlur = false;
window.addEventListener("pageshow", function(evt){
    console.log("debug - common.js - pageshow - showing the page");
}, false);
window.addEventListener("pagehide", function(evt){
    console.log("debug - common.js - pagehide - hiding the page");
    forcePhBlur = true;
}, false);

/*************************** unload ***************************/
var forceUlBlur = false;
window.addEventListener("unload", function(evt){
    console.log("debug - common.js - unload - unloading the page");
    window.onblur = true;
    forceUlBlur = true;
}, false);

/*************************** custom blur logic ***************************/
function delayCheck() {
    console.log("debug - common.js - delayCheck - document.hasFocus(): " +             
    document.hasFocus());
    console.log("debug - common.js - delayCheck - document.hidden: " +        document.hidden);
    if (!document.hasFocus() || document.hidden || forceBlur) {
        delayBlur();  //implemented in the java code
    }
}

var delayVar;

function customBlur() {
console.log("debug - common.js - customBlur - document.hasFocus(): " + document.hasFocus());
console.log("debug - common.js - customBlur - document.hidden: " + document.hidden);
console.log("debug - common.js - customBlur - Document.visibilityState : " + document.visibilityState);
console.log("debug - common.js - customBlur - forceBlur : " + forceBlur);
console.log("debug - common.js - customBlur - forcePhBlur : " + forcePhBlur);
console.log("debug - common.js - customBlur - forceUlBlur : " + forceUlBlur);

if (!document.hasFocus() || document.hidden || forceBlur) {
    console.log("debug - common.js - customBlur - calling delayCheck to blur");
    delayVar = window.setTimeout(delayCheck, 200);
}
AmyW
  • 313
  • 1
  • 2
  • 15
  • Stopping a go home action seems annoying enough to uninstall an app, maybe improve your app so the state cannot be loose in any case and so if the user goes back always continue at the same point? – Ignacio Baca Jan 10 '19 at 17:39
  • The app is similar to a secure testing application like the Safe Exam Browser. It is only used in specific scenarios, and as such includes mandatory reasons for preventing a user from going outside the app. – AmyW Jan 11 '19 at 01:29

2 Answers2

2

Some people went in your same jouney and it could be interesting to dissect their code.

Or you can use Cordova to package your web application into a native app, this will give you ways to access native info through javascript calls.

Luigi Polvani
  • 405
  • 5
  • 9
  • Thank you for your comment! I did look at that library earlier on, but discovered it wouldn't work for what I needed. :) Cordova looks interesting. I've been hearing more about it recently. – AmyW Feb 11 '19 at 13:54
  • If you are interested about going in that direction, you may take a look also at phonegap, it's very similar but seems better supported. https://phonegap.com/ – Luigi Polvani Feb 11 '19 at 16:58
2

The short of it is I don't think it's possible to tell using javascript when the home button is pushed when using a hybrid app. UI events such as page visibility, unloading, etc are not triggered. For reasons I cannot specify, I cannot use timers. Looks like the only option is to edit the swift code for the iPad wrapper to signal when the application enters the background.

AmyW
  • 313
  • 1
  • 2
  • 15