Timer START, STOP, PAUSE, RESUME is possible with Swift 5.x?

Hi everyone!

Since I can't update Xcode to a more recent version and I stayed at swift 4, I ask you one thing: in the latest versions of the language has the management of the "timer" been improved?

That is, is it now possible to pause the timer and have it start again where it stopped without any problems?

So far with version 4 I can only do ".invalidate()", which effectively stops it, but also deletes it not giving me a chance to start over where it came from...

A thousand thanks!

1 Like

What'd be the difference between start/stop and resume/pause?

to pause (or "stop"?) timer set its fireDate to distantFuture
to resume (or "start") timer set its fireDate back (e.g. set it to "Date()" to resume timer instantly.

Note there is no way to resume one-shot timers as they are invalidated.

Edit: potential implementation of pause/resume if I got your intentions right:

extension Timer {
    var isPaused: Bool {
        fireDate > .farEnough
    }
    func pause() {
        if !isPaused {
            fireDate = .farEnough + (fireDate - Date())
        }
    }
    func resume() {
        if isPaused {
            fireDate = Date() + (fireDate - .farEnough)
        }
    }
}

extension Date {
    static let farEnough = Date(timeIntervalSince1970: 100*365*24*60*60)
    static func - (a: Self, b: Self) -> TimeInterval {
        a.timeIntervalSince(b)
    }
}
Edit 2: About the bug above and how to fix it.

There's a bug in the above implementation in that sometimes fireDate.timeIntervalFromNow is negative, which is not a problem per se but translates into an error down the line:

var isPaused: Bool {
    fireDate > .farEnough // TODO: FIX
}

which won't work correctly when fireDate was set to farEnough + a negative delta.
*The fix is simple: either make sure the delta is non negative (max(0, delta)) or modify the comparison above to check for an earlier date: *

var isPaused: Bool {
    fireDate > .farEnough - someLeeway
}

Also note that farEnough is set to be around (just) 2070. I tried bigger numbers (including distantFuture) but there are some internal limits in timer implementation which prohibits scheduling timers for such distant dates.

1 Like