Idle Timer Handling in iPhone Games

Idle Timer Handling in iPhone Games

I just came across the problem of handling disabling and reenabling the idle timer within an iPhone app. In RRRunner as pure motion input based game there are longer intervals without touch input activity. So the system might turn off the screen during the game. Here is a small piece of code how to manage this.

Games that rely completely on motion input or mapping apps are affected by this problem as the user might have configured a small Auto Lock interval like 1 minute. Then the device reduces brightness and will go to sleep after some 15 seconds. This forces the user to tap on the screen without any other benefit just to prevent standby mode.

Apple provides a property for disabling the idle timer completely: UIApplication.idleTimerDisabled. It works but there are situations where it has some side effects that need tweaking. Consider a game that has motion input only while playing, but on game over the user needs to tap the Play Again button. Obviously we don’t want any idle timer being active while playing. On the other hand it is reasonable to activate the timer when in menu mode waiting for touch screen input. The same applies for YouTube app: You watch a 10 minute video without timeout but afterwards it should be active again.

OK, then let’s set the timer active or inactive depending on the app state. When playing it will be disabled and in menu mode it will be enabled again. The problem comes up when reactivating the time by UIApplication.idleTimerDisabled = NO . If the configured auto lock time less than or equal to the amount of time elapsed between disabling and enabling it again, the screen’s brightness is reduced immediately after the call i.e. the timer is counting all the time even when disabled. There is no chance to reset the timer and tell it to restart counting down.

Inspired by the Stack Overflow post iPhone: Detecting user inactivity/idle time since last screen touch I wrote a small class to encapsulate the UIApplication.idleTimerDisabled  calls and perform them delayed. Opposing to the Stack Overflow suggestions and some other posts I wanted to isolate the feature, and I didn’t like the idea of subclassing because of adding just one feature. So the result is just a very simple singleton class containing 3 methods:


   - (void) enableIdleTimerDelayed {
        [self performSelector:@selector (enableIdleTimer) withObject:nil afterDelay:delay];
    - (void) enableIdleTimer {
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
        [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
    - (void) disableIdleTimer {
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
        [[UIApplication sharedApplication] setIdleTimerDisabled:YES];


Call [[IdleTimerManager sharedInstance] disableIdleTimer] to deactivate the timer, [[IdleTimerManager sharedInstance] enableIdleTimerDelayed] when entering the menu or whatever should run with idle timer active and [[IdleTimerManager sharedInstance] enableIdleTimer] is called from your AppDelegate’s applicationWillResignActive method to ensure all your changes are reset properly to the system default behaviour.

The idea behind is just delaying the call to setIdleTimerDisabled:NO by a specified time interval delay for which I choose 60 seconds, the smallest possible auto lock in iOS system setttings. NSObject’s performSelector method let you specify a delay and cancelPreviousPerformRequestsWithTarget cancels every queued call – that’s it no explicit NSTimer instance needed.

The source code at github is under MIT license so feel free to use it as you like. It contains some overhead for singleton management. Replace this if you use a more sophisticated singleton handling macro like Matt Gallaghers CWLSynthesizeSingleton.h (see also his noteworthy article about Singletons, AppDelegates and top-level data).


Comments are closed.

Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu <a href="">Mehr</a><br/>By continuing to use the site, you agree to the use of cookies. More

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.