Search code examples
iosswift

Continue to run a count up when an app goes to the background in iOS


Since I couldn't find a meditation timer that fit what I needed for my health, I decided to write my own. This is a simple application that counts time until you reach the desired time (5 min, 10 min, etc). The idea is to set the time, close the phone, put it in my pocket, and have the phone vibrate (or chime if sound is enabled) when the time is done, this way I can meditate for the period I need and be done.

The problem is that, iOS stops the timer when the app goes to the background or looses focus (screen locks). Yes, I've read that you can use scenePhase and capture the date/time when the scene changes and calculate elapsed time when it goes back into active. The problem with this is that I need the app to alert me when time is done, even if the app is not active. So the counter needs to continue to count, calculating the lapsed time between inactive/active scenes will not help here.

So, again, I'm trying to count time, also when the app goes to the background or the phone locks. The same functionality that iOS's timer app has, that if you set a timer, it continues to run even if the phone locks. I hope it's clear.

Right now I have the code on a Timer, which doesn't work. It's a simple timer, the usual:

@State private var timeRemaining = 100
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

.onReceive(timer) { time in
    if timeRemaining > 0 {
        timeRemaining -= 1
    }
}

I have tried searching Stackoverflow, which led me to this perfectly asked question which states the same problem I have, but for some reason the problem got lost in translation. I did try the code that Rob suggested, which led me to the comments above that calculating the elapse time doesn't work, since I need the app to remain in the background.

I also check other sources, like this one, which suggest a similar thing using timeIntervalSince to calculate time elapsed.

Many others talk about similar approaches.

So, is there a way to have a timer/count/minutes tick continue when the phone locks or the app goes into the background? If yes, what can I use? I have run out of things to try.

Thank you for the help.


Solution

  • The short answer is "You can't do that." Apple can, but third party apps cannot. (At least not unless the phone is jailbroken.)

    With only a few exceptions, Apple does not allow apps to run continuously in the background. Those exceptions are things like turn-by-turn directions apps, music players, and VoIP apps. You have to apply for those app types with Apple, and they won't let you lie and claim your app is a music player when it's not.

    For personal use, you should be able set up your app as a "trojan horse" music player and make it run indefinitely from the background.

    Note that it is possible to schedule a local notification for a future time, and those can trigger vibration or playing a sound. That's probably your best bet here.