9

Working in playground with Swift 3.0 I have this code:

struct Test {
    func run() {
        var timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { timer in
            print("pop")
        }
    }
}

let test = Test()
test.run()

But nothing is printing to console. I've read How can I use NSTimer in Swift? and most of the usage of timer that I've seen in answers and tutorials online involves a selector so I tried this:

class Test {
    func run() {
        var timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.peep), userInfo: nil, repeats: false)
    }

    @objc func peep() {
        print("peep")
    }
}

let test = Test()
test.run()

Still nothing seems to print to console. If I add timer.fire(), then I get the console prints, but obviously that defeats the purpose. What do I need to change to get the timer to run?

EDIT:

So adding CFRunLoopRun() after I called the run method for my Test struct did the trick. Much Thanks to those who answered, especially @AkshayYaduvanshi (who's comment pointed me to CFRunLoopRun()) and @JoshCaswell (whose answer brought up the fact that I timer only works with a run loop).

Community
  • 1
  • 1
Mercutio
  • 1,152
  • 1
  • 14
  • 33

2 Answers2

25

Your first version works if you allow the Playground to run indefinitely via PlaygroundSupport:

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true 

let timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { timer in
  print("Timer Fired at: \(timer.fireDate)")
}

Adding a run loop manually also works, and might be needed sometimes, but in your case this simple instruction is enough to make the Timer work properly.

Durul Dalkanat
  • 7,266
  • 4
  • 35
  • 36
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
8

You need to start a run loop.

RunLoop.main.run(until: Date(timeIntervalSinceNow: 3))

The timer doesn't do anything unless there is a working run loop accepting input. The program simply ends.

Timer reference:

Timers work in conjunction with run loops. [...] it fires only when one of the run loop modes to which the timer has been added is running and able to check if the timer’s firing time has passed.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Thanks for the rapid response. I missed that in the reference, I have to do some reading and testing before I can be sure, but this seems like the problem cause I'm not using runloops at all. – Mercutio Oct 14 '16 at 19:51