How to run a timer-based app at the same speed when the screensaver is active

57 views Asked by At

I wrote a pseudo real-time simulation MacOS app that uses an NSTimer. I'd like to run the app for hours or possibly days. My problem is the app doesn't run in real-time when the screensaver turns on, the computer goes to sleep, or the monitor is off. When I use an app to prevent the computer/display from going to sleep and a "Hot Corner" to disable the screensaver, the app runs in real-time as expected.

Here are steps to reproduce the issue

  1. Create a new MacOS "App" project
  2. Replace the fcode in ViewController.swift with the following code
  3. Run the app
  4. Activate the screensaver or turn off the monitor

class ViewController: NSViewController {
    var startTime:Date?
    override func viewDidLoad() {
        super.viewDidLoad()
        var maxValue:TimeInterval = -1e20
        // Create a Timer that fires every second
        let timer = Timer(timeInterval: 1, repeats: true) { [weak self] _ in
            if let delta = self?.startTime?.timeIntervalSinceNow {
                let value = abs(delta)
                if value > maxValue {
                    maxValue = value
                }
                print("delta: \(value) max: \(maxValue)")
            }
            self?.startTime = Date()
        }
        RunLoop.current.add(timer, forMode: RunLoop.Mode.default)
    }
}

The closure code should fire once per second. With the screensaver on, the code executes about once every 11 seconds.

From Apple's NSTimer documentation,

A timer is not a real-time mechanism. If a timer’s firing time occurs during a long run loop callout or while the run loop is in a mode that isn't monitoring the timer, the timer doesn't fire until the next time the run loop checks the timer. Therefore, the actual time at which a timer fires can be significantly later

Question: Does anyone know how to create a time-based app that fires at the same rate with the screensaver on or the monitor off?

OS: MacOS 10.15.3, SDK: Xcode 11.3

0

There are 0 answers