Timer.scheduledTimer does not work in Swift 3 Timer.scheduledTimer does not work in Swift 3 ios ios

Timer.scheduledTimer does not work in Swift 3


I found that creating the timer in an OperationQueue Operation did not work. I assume this is because there is no runloop.

Therefore, the following code fixed my problem:

DispatchQueue.main.async {    // timer needs a runloop?    self.timeoutTimer = Timer.scheduledTimer(timeInterval: self.timeout, target: self, selector: #selector(self.onTimeout(_:)), userInfo: nil, repeats: false)}


Timer methods with a selector are supposed to have one parameter: The timer itself. Thus your code should really look like this: 1

Timer.scheduledTimer(timeInterval: 1.1,     target: self,     selector: #selector(self.adjustmentBestSongBpmHeartRate(_:),     userInfo: nil,     repeats: false)@objc func adjustmentBestSongBpmHeartRate(_ timer: Timer) {    print("frr") }

Note that if your app only runs on iOS >= 10, you can use the new method that takes a block to invoke rather than a target/selector. Much cleaner and more type-safe:

class func scheduledTimer(withTimeInterval interval: TimeInterval,     repeats: Bool,     block: @escaping (Timer) -> Void) -> Timer

That code would look like this:

 timer = Timer.scheduledTimer(withTimeInterval: 1.1,         repeats: false) {    timer in    //Put the code that be called by the timer here.    print("frr")    }

Note that if your timer block/closure needs access to instance variables from your class you have to take special care with self. Here's a good pattern for that sort of code:

 timer = Timer.scheduledTimer(withTimeInterval: 1.1,         repeats: false) {    //"[weak self]" creates a "capture group" for timer    [weak self] timer in    //Add a guard statement to bail out of the timer code     //if the object has been freed.    guard let strongSelf = self else {        return    }    //Put the code that be called by the timer here.    print(strongSelf.someProperty)    strongSelf.someOtherProperty = someValue    }

Edit (updated 15 December)

1: I should add that the method you use in the selector has to use Objective-C dynamic dispatch. In Swift 4 and later, the individual methods you reference must be tagged with the @objc tag. In previous versions of Swift you could also declare the entire class that defines the selector with the @objc qualifier, or you could make the class that defined the selector a subclass of NSObject or any class that inherits from NSOBject. (It's quite common to define the method the timer calls inside a UIViewController, which is a subclass of NSObject, so it used to "just work".


Swift 3

In my case it worked after I added to my method the @obj prefix

Class TestClass {   private var timer: Timer?   func start() {        guard timer == nil else { return }        timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(handleMyFunction), userInfo: nil, repeats: false)    }    func stop() {        guard timer != nil else { return }        timer?.invalidate()        timer = nil    }    @objc func handleMyFunction() {        // Code here    }}