UIApplication.shared.isIdleTimerDisabled not working all night?

To allow my app to run during the night, I use:


UIDevice.current.isProximityMonitoringEnabled = true
UIApplication.shared.isIdleTimerDisabled = true


The screen goes dark when the user places the phone face-down on the nightstand. I start a timer at this point to perform URL fetches and update the app every 10 minutes or so throughout the night.


This starts and appears to work just as it did in iOS 10. But it's never still running by morning, as it was with iOS 10. I see no indications of a problem, it's just not making it all night anymore.


I'm not sure how to even diagnose this. I can add a print statement to my logging to determine exactly when it stops during the night but that won't tell me why.

Replies

I have more data on this problem now. I put my iPhone face down last night at 11:51PM. My log file shows that the proximity detector was active and I saw the screen dim as I laid it down.


My timer is set to run repeatedly every 610 seconds after the proximity detector is turned on, which it did successfully ten times until 1:33AM. (That's 142 minutes and the math works out.)


At 1:36AM, my app responed to a background fetch, meaning it was in the background at that time and the timer was no longer running. Background fetches continued every few minutes until 1:51AM and didn't resume until 7:14AM. They then continued every few minutes.


What happened at 1:33AM in the morning to stop my timer and put the app into the background? Is there a better way to ensure all-night running?


Here's my timer code. I didn't set the tolerance previously because I couldn't find syntax for doing that without errors until now. Maybe that wold help?

    weak var timer: Timer?
    func startTimer() {
        timer?.tolerance = 60  // This does not throw an error but I haven't tested it.  
        timer = Timer.scheduledTimer(withTimeInterval: 610.0, repeats: true) { [weak self] _ in
            self?.logSB.warning("The timer triggered at \(Date())")  // I use SwiftyBeaver logging
            self?.didEnterForeground()  // This triggers UI changes and other actions
        }
    }
  
    func stopTimer() {
        timer?.invalidate()
    }

It seems to be more reliable now that I've set the tolerance on my timer, as above. It's run throughout the night several nights in a row.