Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resume JavaScript timer on iOS8 web app after screen unlock?

On iOS8 this HTML5 web app does not resume the js timer after the screen is locked and then unlocked if the webapp was active AND launched from the homescreen icon. On iOS7 the timer would continue in this situation. I need the timer to continue after the screen is unlocked - any tips to achieve this?

Note/ Please add the web app to the homescreen first using Safari's "add to home screen" via the sharing button. Running the page inside Safari does not cause the issue described above.

<html>
<head>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <title>Test</title>
    <script>
        var tim;
        function go() {
            tim = window.setInterval(action, 1000);
        }
        function action() {
            document.getElementById('x').innerHTML = new Date().getTime().toString();
        }
    </script>
</head>
<body onload="go()">
    <div id="x"></div>
</body>
</html>
like image 778
ajayel Avatar asked Sep 24 '14 04:09

ajayel


2 Answers

Installing iOS 8.1.1 fixes this problem

like image 33
ajayel Avatar answered Oct 14 '22 04:10

ajayel


The solution we ended up does not address all the broken functionality after sleep mode in IOS8, but rather just ajax requests/setTimeout/setInterval/requestAnimationFrame and their respective clear functions.

Other things broken after sleep mode:

  • -webkit-transition opacity causes non-selectable areas
  • worker.postMessage called while keyboard opening permanently kills all WebWorkers
  • window bouncing/panning can kill all WebWorkers.
  • overflowchange/resize events no longer work. You need to rework any logic that depends on them`.

To make a semi-working solution:

  1. Override setTimeout/setInterval/requestAnimationFrame/clearInterval/clearTimeout/cancelAnimationFrame. All of these functions need to postMessage to a webworker, where the webworker will perform setTimeout/setInterval accordingly. You may need to set up a pausing mechinism for these functions as well, but I'm not 100% its necessary.
  2. Override XMLHttpRequest so that when send is called, the request is actually performed on a webworker.
  3. Create a pausing mechanism for all webworkers so that the main thread can determine when all webworkers have flushed their messages (Basically need to prevent postMessage from getting called on any worker while the keyboard is up).
  4. Prevent keyboard popping up on editable elements. After detecting a tap/click event on an editable element, you need to manually call the focus function.
  5. Override focus function on editable elements that open the keyboard. Focus will now call the pause workers function. After all workers are paused, call the browser implementation of focus.
  6. Add focusout event listener to editable elements so that resume workers function is called.

I have a semi-abstracted version on my github available for others. We are using the github version in our fairly complex/large and heavily animation+ajax dependent application with very few issues.

https://github.com/TaDaa/IOS8-FIX

like image 146
TaDaa Avatar answered Oct 14 '22 06:10

TaDaa