Disabling Timer Coalescing in OSX for a given process Disabling Timer Coalescing in OSX for a given process multithreading multithreading

Disabling Timer Coalescing in OSX for a given process


A user on the Apple Developer forums actually recommended I watch a video from WWDC 2013 entitled "Improving Power Efficiency with App Nap"; in which I found the solution:

static dispatch_source_t _keepAliveTimer;+(void)enable{    _keepAliveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, dispatch_get_main_queue());    dispatch_source_set_event_handler(_keepAliveTimer, ^{        // do something    });    dispatch_source_set_timer(_keepAliveTimer, dispatch_time(DISPATCH_TIME_NOW, 1.5 * NSEC_PER_SEC), 1.5 * NSEC_PER_SEC, 0.5 * NSEC_PER_SEC);    dispatch_resume(_keepAliveTimer);}

This piece of code will fire a timer at 1.5 seconds (give or take 0.5 seconds) regardless of the LSUIElement state and will prevent App Nap from kicking in for that timer only.


It sounds like you're running the background application without setting an appropriate .plist key.

If you are using a background application, then you must either set the 'Application is agent (UIElement)' (LSUIElement) option to YES or the 'Application is background only' (LSBackgroundOnly) option to yes in the application's plist, otherwise it will be subject to App Nap, which is what you're experiencing in this case. I would not expect timer coalescing to produce the huge gaps in the timer intervals.

The LSUIElement is intended for apps that may just have a floating window or a status-bar item. They don't get a menu bar, and they don't get a dock icon.

App Nap is designed to affect up-front user applications. There are, according to the docs there are 4 things that will cause the app to be sent into app-nap:

  • It is not visible—if all of an app’s windows are either hidden by other windows or minimized in a hidden dock, and the app is not in the foreground
  • It is not audible
  • It has not explicitly disabled automatic termination
  • It has not taken any power management assertions

If you want to prevent a user application from experiencing App nap, then you will have to follow one of the supported mechanisms for causing one of these states to not be active.

If you use the IOPmlib.h API, you can create a power management assertion for your app which will prevent app nap.

Alternativaly, you can disable automatic termination using:

[[NSProcessInfo processInfo] disableAutomaticTermination:@"Good Reason"];

And to enable automatic termination again:

[[NSProcessInfo processInfo] enableAutomaticTermination:@"Good Reason"];

But this is generally intended for code that needs to be done before an app is considered 'good to stop' e.g. writing out preferences.

Apple do state somewhere in the docs that if your app is experiencing issues related to app nap that you should file a radar so that it can be determined if it's a bug in their implementation.