33

I need to schedule a Timer for firing a function every second but I see that in Xcode 8 beta 3 the scheduledTimer is only available for iOS 10.

Is there any alternative for using the timer in iOS 9 or previous versions?

Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in print("Hi!")})
pkamb
  • 33,281
  • 23
  • 160
  • 191
rockdaswift
  • 9,613
  • 5
  • 40
  • 46

8 Answers8

57

Solved using

Timer.scheduledTimer(timeInterval: 1,
                           target: self,
                         selector: #selector(self.updateTime),
                         userInfo: nil,
                          repeats: true)
Haroldo Gondim
  • 7,725
  • 9
  • 43
  • 62
rockdaswift
  • 9,613
  • 5
  • 40
  • 46
  • If you wish you can use `if #available(iOS 10, *) { //iOS 10 code } else { //iOS 9 code }` to support both depending on the OS version. – Awesomeness Feb 21 '17 at 21:41
  • I needed to add write the target function like this: `@objc func updateTime() {}` – Jonny Mar 29 '17 at 03:35
  • 1
    It's also worth looking at the lower posts to see how Timer's are stopped. It may not get removed from the run loop properly if it's not removed manually. – kbpontius Jun 11 '17 at 08:03
  • Hy I am new to swift, just a basic question, what does userInfo represents in scheduledTimer function?? – prasoonraj Dec 08 '21 at 04:41
  • Hi @prasoonraj, I guess that it means that you can pass a dictionary with any useful information every time the timer is fired. – rockdaswift Dec 08 '21 at 21:40
17

Run a timer with swift3,

var timer: Timer?

func startTimer() {

    if timer == nil {
        timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.loop), userInfo: nil, repeats: true)
    }
}

func stopTimer() {
    if timer != nil {
        timer?.invalidate()
        timer = nil
    }
}

func loop() {
    let liveInfoUrl = URL(string: "http://192.168.1.66/api/cloud/app/liveInfo/7777")
    let task = URLSession.shared.dataTask(with: liveInfoUrl! as URL) {data, response, error in
        guard let data = data, error == nil else { return }
        print(String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) ?? "aaaa")
    }
    task.resume()
}

Release the timer when you not use it.

Once scheduled on a run loop, the timer fires at the specified interval until it is invalidated. A nonrepeating timer invalidates itself immediately after it fires. However, for a repeating timer, you must invalidate the timer object yourself by calling its invalidate() method.

LF00
  • 27,015
  • 29
  • 156
  • 295
8

Here is sample code workable with compatibility:

if #available(iOS 10.0, *) {
    Timer.scheduledTimer(withTimeInterval: 15.0, repeats: true){_ in
        // Your code is here:
        self.myMethod()
    }
} else {      
    Timer.scheduledTimer(timeInterval: 15.0, target: self, selector: #selector(self.myMethod), userInfo: nil, repeats: true)
}

//Your method or function:

// MARK: -  Method

@objc func myMethod() {
    print("Hi, How are you.")
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Incredible_Dev
  • 956
  • 7
  • 13
3

Swift 3

func runCode(in timeInterval:TimeInterval, _ code:@escaping ()->(Void))
{
    DispatchQueue.main.asyncAfter(
        deadline: .now() + timeInterval,
        execute: code)
}

func runCode(at date:Date, _ code:@escaping ()->(Void))
{
    let timeInterval = date.timeIntervalSinceNow
    runCode(in: timeInterval, code)
}

func test()
{
    runCode(at: Date(timeIntervalSinceNow:2))
    {
        print("Hello")
    }

    runCode(in: 3.0)
    {
        print("World)")
    }
}
hhamm
  • 1,511
  • 15
  • 22
3

Updated for swift 3:

If you want to use Timer for some delay or any other purpose used below lines of code in your project;

// function defination:

func usedTimerForDelay()  {
    Timer.scheduledTimer(timeInterval: 0.3,
                         target: self,
                         selector: #selector(self.run(_:)),
                         userInfo: nil, 
                         repeats: false)
}

func run(_ timer: AnyObject) {
      print("Do your remaining stuff here...")

}

// function call:

self.usedTimerForDelay()

NOTE:- you can change the time interval as you want.

//Enjoy coding..!

Kiran Jadhav
  • 3,209
  • 26
  • 29
1
Timer.scheduledTimer

Put it in the main thread.

senlinmu
  • 141
  • 2
  • 11
1

You can use the following simple shim to provide the new block-based Timers to pre-iOS 10:

class TimerShim {
    private var timer: Timer?
    private let block: (Timer) -> Void

    private init(timeInterval interval: TimeInterval, repeats: Bool, block: @escaping (Timer) -> Void) {
        self.block = block
        timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(timerDidFire), userInfo: nil, repeats: repeats)
    }

    class func scheduledTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping (Timer) -> Void) -> Timer {
        return TimerShim(timeInterval: interval, repeats: repeats, block: block).timer!
    }

    @objc private func timerDidFire() {
        block(timer!)
    }
}

Usage example:

TimerShim.scheduledTimer(withTimeInterval: 5, repeats: false) { _ in
    print("boom!")
}
Jonathan Ellis
  • 5,221
  • 2
  • 36
  • 53
-5

The correct form is:

Timer.scheduledTimer(withTimeInterval: 2, repeats: false){_ in
   "Here your code method"
}
Kike Gamboa
  • 994
  • 7
  • 8