Do something every x minutes in Swift

How can I run a function every minute? In JavaScript, can I do something like setInterval , does something like this exist in Swift?

Required Conclusion:

Hello world once a minute ...

+83
ios swift repeat setinterval intervals
Sep 20 '14 at 18:24
source share
6 answers
 var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true) func sayHello() { NSLog("hello World") } 

Remember to import Foundation.

Swift 4:

  var helloWorldTimer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(ViewController.sayHello), userInfo: nil, repeats: true) @objc func sayHello() { NSLog("hello World") } 
+137
Sep 20 '14 at 18:34
source share

In Swift 3, you can create a Timer . And, if you use targeting on iOS version 10 and above, you can use block-based markup, which simplifies potential strong link loops, for example:

 weak var timer: Timer? func startTimer() { timer?.invalidate() // just in case you had existing `Timer`, `invalidate` it before we lose our reference to it timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { [weak self] _ in // do something here } } func stopTimer() { timer?.invalidate() } // if appropriate, make sure to stop your timer in `deinit` deinit { stopTimer() } 

In Swift 2, you create NSTimer . And if you use Swift 2, you can use the iOS version up to 10.0, in which case you will have to use the older target / selector pattern:

 weak var timer: NSTimer? func startTimer() { timer?.invalidate() // just in case you had existing `NSTimer`, `invalidate` it before we lose our reference to it timer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true) } func handleTimer(timer: NSTimer) { // do something here } func stopTimer() { timer?.invalidate() } // because this old target/selector approach will keep a strong reference // to the `target`, if you want the timer to stop when the view controller // is dismissed, you can't stop the timer in `deinit`, but rather have to // detect the dismissing of the view controller using other mechanisms. Commonly, // we used to detect the view disappearing, like below: override func viewDidDisappear(animated: Bool) { super.viewDidDisappear(animated) stopTimer() } 



Although NSTimer is usually best for completeness, I should note that you can also use a send timer, which is useful for scheduling timers on background threads. When sending timers, since they are block-based, this avoids some strong support loop problems with the old target / <T24> NSTimer model, as long as you use weak links.

So, in Swift 3:

 var timer: DispatchSourceTimer? func startTimer() { let queue = DispatchQueue(label: "com.domain.app.timer") // you can also use `DispatchQueue.main`, if you want timer = DispatchSource.makeTimerSource(queue: queue) timer!.scheduleRepeating(deadline: .now(), interval: .seconds(60)) timer!.setEventHandler { [weak self] in // do whatever you want here } timer!.resume() } func stopTimer() { timer?.cancel() timer = nil } deinit { self.stopTimer() } 

In Swift 2:

 var timer: dispatch_source_t? func startTimer() { let queue = dispatch_queue_create("com.domain.app.timer", nil) // again, you can use `dispatch_get_main_queue()` if you want to use the main queue timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue) dispatch_source_set_timer(timer!, DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC, 1 * NSEC_PER_SEC) // every 60 seconds, with leeway of 1 second dispatch_source_set_event_handler(timer!) { [weak self] in // do whatever you want here } dispatch_resume(timer!) } func stopTimer() { if let timer = timer { dispatch_source_cancel(timer) self.timer = nil } } deinit { self.stopTimer() } 

For more information, see the โ€œCreating a Timerโ€ section in the sample send source in the Debugging Files section of the Concurrency Programming Guide.

+113
Sep 20 '14 at 19:51
source share

Here's the update for the NSTimer answer for Swift 3 (in which NSTimer was renamed to Timer ) using a closure rather than a named function:

 var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { (_) in print("Hello world") } 
+14
02 Dec '16 at 23:48
source share

You can use NSTimer

 var timer = NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("function"), userInfo: nil, repeats: true) 

In the selector () you enter the name of your function

+10
Sep 20 '14 at 18:30
source share

In swift 3.0, GCD got refactoring:

 let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) timer.scheduleRepeating(deadline: .now(), interval: .seconds(60)) timer.setEventHandler { NSLog("Hello World") } timer.resume() 

This is especially useful when you need to send a separate queue. In addition, if you plan to use this to update the user interface, I suggest CADisplayLink look at CADisplayLink , as it is synchronized with the GPU refresh rate.

+7
Nov 30 '16 at 20:58
source share

If you can afford some drift time here is a simple solution that executes some code every minute:

 private func executeRepeatedly() { // put your code here DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in self?.executeRepeatedly() } } 

Just run executeRepeatedly() once and it will execute every minute. Execution is terminated when the owner object is freed. You can also use a flag indicating that execution should be stopped.

+2
Mar 02 '18 at 17:42
source share



All Articles