swift calculate time for timers running in backgro

2019-02-21 00:25发布

I want to run 2 interchangeable timers but I want them to "run" even if the app is in the background.

The desirable behavior is, that user starts the timer, goes background and just waits for notifications for the interchangeable timers to trigger ... the timers can interchange a lot of times. When the user brings the app back to foreground .. he wants to see the accurate time of the current timer.

Timers do work in background when in iOS Simulator, but not on a device ...

The interchangeable times According to the picture I attached, I am trying to calculate the X The time when the current timer should expire and acquire the current time according to the end time. The code follows:

func appDidBecomeActive(){
// TODO: calculate time spend in background
isInBackground = false

if let startTime = startTime{
    let now = NSDate()
    var timeFromBegining = now.timeIntervalSinceDate(startTime)

    while timeFromBegining > userDefaultsHelper.timerAseconds(){
        timeFromBegining -=  userDefaultsHelper.timerAseconds()
        timerType = .tiemrTypeB

        let stopTimeSeconds = userDefaultsHelper.timerBseconds() - timeFromBegining
        stopTime = NSDate().dateByAddingTimeInterval(stopTimeSeconds)
        print("Time from Begining: \(timeFromBegining)")

        if  timeFromBegining > userDefaultsHelper.timerBseconds(){
            timeFromBegining -= userDefaultsHelper.timerBseconds()
            timerType = .timerTypeA

            // TODO: do something with the remaining time ...
            let stopTimeSeconds = userDefaultsHelper.timerAseconds() - timeFromBegining
            stopTime = NSDate().dateByAddingTimeInterval(stopTimeSeconds)
            print("Time from Begining: \(timeFromBegining)")
        }
    }
}
}

1条回答
贪生不怕死
2楼-- · 2019-02-21 00:43

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 = NSDate().timeIntervalSinceDate(startTime)

let totalDuration = durationOfTimerA + durationOfTimerB

let whereInCycle = elapsed % 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)")
查看更多
登录 后发表回答