CodeNinja
CodeNinja

Reputation: 626

Swift Dispatch Source Timer doesn't fire as scheduled

I have a timer declared as the following:

var timer: DispatchSourceTimer?

override func viewDidLoad() {
    super.viewDidLoad()

    ...

    timer = DispatchSource.makeTimerSource()
    timer!.scheduleRepeating(deadline: .now() + .seconds(60), interval: .seconds(3600), leeway: .seconds(1))
    timer!.setEventHandler { [weak self] in
        self?.saveData()
    }
    timer!.resume()
    print("TIMER HAS STARTED")
}

This code is executed in my viewDidLoad method, and fires correctly the first time after the 1 min delay I included. It is then supposed to fire every hour. I ran my app in the simulator keeping it constantly on and in focus. In fact it is still running.

The first time the data was saved I logged a time of 11:45am. It was not saved again until 1:00pm, and then at 2:08. What am I missing?

EDIT: When testing this timer I was able to get data every minute, but for the actual application I need it to do it every hour.

Upvotes: 0

Views: 2843

Answers (1)

Glenn Posadas
Glenn Posadas

Reputation: 13283

In my case, the DispatchSourceTimer does not fire the event when I make an instance of it inside the viewDidLoad, not really sure why, tried it multiple times.

So just make sure you have your DispatchSourceTimer as a property, and also you could just try to shorten the interval and the delay parameter of the DispatchSourceTimer's schedule for the sake of testing, like so:

// MARK: - Properties

var timer: DispatchSourceTimer!

// MARK: - Functions
// MARK: Overrdes

override func viewDidLoad() {
    super.viewDidLoad()

    timer = DispatchSource.makeTimerSource()
    timer.schedule(deadline: .now() + .seconds(1), repeating: .seconds(5), leeway: .seconds(1))
    timer.setEventHandler(handler: { [weak self] in
        guard let strongSelf = self else { return }
        strongSelf.saveData()
    })

    timer.resume()
}

func saveData() {
    print("❇️Invoked...")
}

Upvotes: 2

Related Questions