Swift Calculate Time for Timers Running in Background

How to properly measure elapsed time in background in Swift

Ok, like I mention in the edit 2 of the question:
The first issue was because "seconds" is a Int and then it almost always gains or lose when converting it from Double.

But the main problem was that i had to invalidate the timer when the app enter in background and i didn't.

So now with invalidating the timer when the app gets the notification that will enter background and then starting it when it enter foreground everything works fine.

swift calculate time for timers running in background

Personally, I'd consider the combined duration of A and B to be one "cycle". And then, when the app restarts, I'll do the modulus calculations to determine (a) how many cycles have past since timer A was started the first time; and (b) calculate where we are within the current cycle. From that you can easily calculate the amount of time left until the next occurrence of each timer:

let elapsed = Date().timeIntervalSince(startTime)

let totalDuration = durationOfTimerA + durationOfTimerB

let whereInCycle = elapsed.remainder(dividingBy: totalDuration)
let cycleCount = Int(elapsed / totalDuration)

var timeUntilNextA: Double
var timeUntilNextB: Double

if whereInCycle < durationOfTimerA {
timeUntilNextA = durationOfTimerA - whereInCycle
timeUntilNextB = timeUntilNextA + durationOfTimerB
} else {
timeUntilNextB = durationOfTimerA + durationOfTimerB - whereInCycle
timeUntilNextA = timeUntilNextB + durationOfTimerA
}

if cycleCount < 1 {
if whereInCycle < durationOfTimerA {
print("timer A hasn't fired yet")
} else {
print("timer A has fired, but B hasn't")
}
} else {
if whereInCycle < durationOfTimerA {
print("both timers A and B have fired \(cycleCount) times, and waiting for A to fire next")
} else {
print("timers A has fired \(cycleCount+1) times, but B has fired only \(cycleCount) times; we waiting for B to fire next")
}
}

print("A will fire in \(timeUntilNextA) seconds; B will fire in \(timeUntilNextB)")

Background timer running

Until iOS 12, you could not been able to run your app in background mode, but from iOS 13 (beta) you can.
Apple has added framework BackgroundTasks which can add ability to do some task in background mode.

https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler

Swift timer in background

It's not possible to run timer continuously in the background after a couple seconds apple may discard the timer.

You can do one thing, take one global variable add set current time in applicationDidEnterBackground, and applicationWillEnterForeground check in this method take current system time and stored previous time compare both times and get a difference between them and check is,

if self.currentTime != TIME_SEARCH {
self.currentTime += 1
}
else {
// Time out
self.stopChecking()
}

You have to check here like if self.currentTime > TIME_SEARCH or if self.currentTime < TIME_SEARCH so you can get perfect result. :)



Related Topics



Leave a reply



Submit