Using Nstimer in Swift Playground

Using NSTimer in swift playground

First of all, your onTimer method have to be declared as @objc, or NSTimer cannot find that.

As for your question, it's because you haven't started the run loop.

To do that, CFRunLoopRun() is the simplest solution I think.

import Foundation

class MyClass {

func startTimer() {
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "onTimer:", userInfo: nil, repeats: true)
}

@objc func onTimer(timer:NSTimer!) {
println("Timer here")
}
}

var anInstance = MyClass()

anInstance.startTimer()

CFRunLoopRun() // <-- HERE!

For the sake of completeness, as @MartinR metioned in the comment, you can also use XCPSetExecutionShouldContinueIndefinitely()

import Foundation
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely()

class MyClass {

func startTimer() {
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "onTimer:", userInfo: nil, repeats: true)
}

@objc func onTimer(timer:NSTimer!) {
println("Timer here")
}
}

var anInstance = MyClass()

anInstance.startTimer()

In this case the Playground runs only seconds specified in the Timeline:

screenshot

NSTimer.scheduledTimerWithTimeInterval in Swift Playground

You really should not be using NSTimer these days. It's consumes a lot of resources, causes unnecessary battery drain, and the API lends itself to ugly code.

Use dispatch_after() instead:

dispatch_after(0, dispatch_get_main_queue()) { () -> Void in
for counter in 0...1000 {
var b = counter
}
}

Of course, since the timer will fire after playground does it's stuff you will need an equivalent of timer.fire() to force the code to execute immediately instead of after a 0 second delay. Here's how that works:

let printFrom1To1000 = { () -> Void in
for counter in 0...1000 {
var b = counter
}
}

dispatch_after(0, dispatch_get_main_queue(), printFrom1To1000)

printFrom1To1000()

Timer does not run in Swift 3.0 playground

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.

How can I use Timer (formerly NSTimer) in Swift?

This will work:

override func viewDidLoad() {
super.viewDidLoad()
// Swift block syntax (iOS 10+)
let timer = Timer(timeInterval: 0.4, repeats: true) { _ in print("Done!") }
// Swift >=3 selector syntax
let timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
// Swift 2.2 selector syntax
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyClass.update), userInfo: nil, repeats: true)
// Swift <2.2 selector syntax
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "update", userInfo: nil, repeats: true)
}

// must be internal or public.
@objc func update() {
// Something cool
}

For Swift 4, the method of which you want to get the selector must be exposed to Objective-C, thus @objc attribute must be added to the method declaration.

Can't get my Timer in Swift to fire in Playground

Once a source has been cancelled by dispatch_source_cancel, it will never call its event handler again. You cannot reenable the source with dispatch_resume after cancelling it; you must create a new source.

To make your playground work, you must remove the call to timer.cancel().

Furthermore, after the entire playground script has been executed, the playground process exits by default. If you want it to keep running, you need to set XCPlaygroundPage.currentPage.needsIndefiniteExecution = true.

So make the end of your script look like this:

var timer = Timer()
timer.tick = {
let now = NSDate()
print("\(now)")
}
timer.resume()
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

How can I make a countdown with NSTimer?

Question 1:

@IBOutlet var countDownLabel: UILabel!

var count = 10

override func viewDidLoad() {
super.viewDidLoad()

var timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(UIMenuController.update), userInfo: nil, repeats: true)
}

func update() {
if(count > 0) {
countDownLabel.text = String(count--)
}
}

Question 2:

You can do both. SpriteKit is the SDK you use for scene, motion, etc. Simple View Application is the project template. They should not conflict

Timer Interval not firing

The simple answer is to add this to your playground:

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

When using a playground, by default the playground runs all the code and then stops, it doesn't know to wait for the timer. This code just tells the playground to keep waiting for something to happen.



Related Topics



Leave a reply



Submit