iostimerswift6

How to start timer in actor for in swift 6


I want to use a timer in a background thread to do something like ping in swift 6.

Here is the code:

actor TimerActor {
    var timer: Timer?
    
    func start() {
        timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: { timer in
            Task {
                await self.ping()
            }
        })
        RunLoop.current.add(timer!, forMode: .common)
    }
    
    func ping() {
        print("send ping")
    }
}

usage

class ViewController: UIViewController {
    
    let actor = TimerActor()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        Task {
            await actor.start()
        }
    }
}

The ping() isn't called at all. How to achieve it, thanks!


Solution

  • I came across this as I have a similar issue but I think in general actor (concurrent) context has no information on RunLoop so won't work. I found this which explains but is a little old so not sure if newer recommendations available yet. https://wadetregaskis.com/performing-a-delayed-and-or-repeating-operation-in-a-swift-actor/