setInterval not working in iOS 8 – Home Screen Apps Lose Timing Functions After Lock/Wake

ios_8_logo

If your application is being used as a homescreen web application, you’ll find yourself in a sorry state. Of course, any web app can be converted into a home screen app by the user, so I guess technically this affects anyone making a remote web application. This bug is easily reproduced by simply calling setTimeout(callback, 1) or requestAnimationFrame(callback) via some button or event. When you first open your application, you’ll notice all timing functions are working fine. However if you lock your phone and then unlock to return to your application, you’ll see none of the timing functions can call callbacks anymore. They are simply broken at a native level. There is no reset, no bringing your application back to life, it’s a kill it and restart situation.

These timing functions are crucial to pretty much every other JavaScript framework/library ever made. Definitely head over to Apple as soon as you can, and let them know that you would like to have all of your JavaScript functions, all the time.

Radar Bug Report: http://www.openradar.me/radar?id=5895945212395520

 

Alternative to setInterval and setTimeout

JavaScript’s setTimeout and setInterval are evil and not precise…

  1. both have a delay of various milliseconds http://www.andrewduthie.com/post/a-self-correcting-setinterval-alternative/
  2. both are very resource intensive as they execute several times every second.

A new alternative is requestAnimationFrame. it’s less resource=intensive, does not slow down other stuff and it is disabled on page blur.

This makes it the perfect substitute for a modern setTimeout and setInterval.

So I wrote this functions:

Description

This functions use requestAnimationframe to check if the time is passed based on the elapsed Time calculated from Date.now. The time passed is more precise than the native functions and theoretically less resource intensive. Another advantage/disadvantage(depends) is that the functions are not executed on page blur.

Good for: animations, visual effects

Bad for: timers, clock

RafTimeout

window.rtimeOut=function(callback,delay){
 var dateNow=Date.now,
     requestAnimation=window.requestAnimationFrame,
     start=dateNow(),
     stop,
     timeoutFunc=function(){
      dateNow()-start<delay?stop||requestAnimation(timeoutFunc):callback()
     };
 requestAnimation(timeoutFunc);
 return{
  clear:function(){stop=1}
 }
}

RafInterval

window.rInterval=function(callback,delay){
 var dateNow=Date.now,
     requestAnimation=window.requestAnimationFrame,
     start=dateNow(),
     stop,
     intervalFunc=function(){
      dateNow()-start<delay||(start+=delay,callback());
      stop||requestAnimation(intervalFunc)
     }
 requestAnimation(intervalFunc);
 return{
  clear:function(){stop=1}
 }
}

Usage

var interval1,timeout1;
window.onload=function(){
 interval1=window.rInterval(function(){console.log('interval1')},2000);
 timeout1=window.rtimeOut(function(){console.log('timeout1')},5000);
}

/* to clear
interval1.clear();
timeout1.clear();
*/

Demo

http://jsfiddle.net/wZ9Z6/

Advertisements