I'm working on a macOS app (let's call it the "display app") that displays a clock and other data, which is controlled by another app (the "control app") on the same machine via a TCP connection. I have noticed that when the display app is idle for some time (> 60 sec.) and then schedules an NSTimer (with a .2 second interval), it takes a very long time before the timer fires for the first time (in the range of 6-10 seconds, sometimes longer.) That happens mostly when the display app is not frontmost (because the control app is.) Once the timer fired for the first time, it works as expected (with some small, expected delays in the timer) for some time.
But when the timer is running for a long time (more than 5 minutes), there are similar extreme delays between firing (also 6-10 seconds.) It looks like manually scheduling the timer with
[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
postpones the problem a bit (using [NSTimer scheduledTimer...]
makes that problem appear sooner than when manually adding it to the runloop.)
This causes a lot of trouble because the clock is not updating during that time.
I assume this happens because macOS considers the display app "idle" or "inactive" in some way.
Is there a way to prevent, control, or circumvent this behaviour?
This is App Nap. The display app can do the following to avoid napping:
When it can allow napping again, you should do: