How do I make a DispatchSourceTimer run reliably in the background?

Greetings,


I have a Mac OS application, written in Swift, that needs to send out timing messages periodically. I have written it to use a DispatchSourceTimer whose handler sends out UDP packets over the network. As long as the application is in the foreground, all works as expected and the packets get sent in a timely manner. However, if another application becomes the foreground application, then after some time the timer will start to fire sporadically, missing most of its deadlines.


I suspect that I need to create my own DispatchQueue for the timer with an appropriate QoS setting that make it continue to run with high enough priority even when my app is in the background, but the documentation is sketchy as to exacly what the different QoS levels mean and which one will accomplish what I need.


Suggestions?


Thanks,

--Douglas Mandell

Replies

I have a Mac OS application …

Just to confirm, this is macOS, right? I see this question a lot, but it’s mostly from iOS folks who missed the memory about apps being suspended in the background.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Quinn (or should I call you "Eskimo"?),


Yes, Mac OS it is. I realized after I had placed the original post that I hadn't specified, and edited it accordingly.


My app continues to run correctly for some time after moving to the background, but I would like to know how to make it keep running correctly in the background. The app will eventually be doing some audio processing too which must also continue to run no matter what.


Thanks,

--Douglas Mandell

You are probably falling victim to App Nap, which can delay timers. You can use techniques described in the Energy Efficiency Guide for Mac Apps to control that. See the articles in the Prioritize Work and Schedule Work sections.