Haz algo cada x minutos en Swift

¿Cómo puedo ejecutar una función cada minuto? En JavaScript puedo hacer algo como setInterval , ¿existe algo similar en Swift?

Resultado deseado:

Hola Mundo una vez por minuto …

 var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true) func sayHello() { NSLog("hello World") } 

Recuerde importar Fundación.

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") } 

En Swift 3, puedes crear un Timer . Y si se dirige a iOS versión 10 y superior, puede usar la representación basada en bloques, lo que simplifica los fuertes ciclos de referencia potenciales, por ejemplo:

 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() } 

En Swift 2, creas un NSTimer . Y si está usando Swift 2, es posible que esté utilizando una versión de iOS anterior a la 10.0, en cuyo caso debe usar el patrón de target / selector :

 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() } 

Si bien NSTimer es generalmente el mejor, en aras de la exhaustividad, debería tener en cuenta que también puede usar el temporizador de envío, que es útil para progtwigr temporizadores en hilos de fondo. Con los temporizadores de envío, dado que están basados ​​en bloques, evita algunos de los desafíos de ciclo de referencia fuertes con el patrón de target / selector antiguo de NSTimer , siempre que use referencias weak .

Entonces, en 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() } 

En 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() } 

Para obtener más información, consulte la sección Creación de un temporizador de Ejemplos de origen de envío en la sección Fuentes de despacho de la Guía de progtwigción de simultaneidad.

Aquí hay una actualización de la respuesta de NSTimer , para Swift 3 (en la cual NSTimer fue renombrado como Timer ) usando un cierre en lugar de una función nombrada:

 var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { (_) in print("Hello world") } 

Puedes usar NSTimer

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

En selector () ingresas el nombre de tu función

En swift 3.0 el GCD se refactorizó:

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

Esto es especialmente útil para cuando necesita despachar en una Cola en particular. Además, si planea usar esto para la actualización de la interfaz de usuario, le sugiero que busque en CADisplayLink ya que está sincronizado con la frecuencia de actualización de la GPU.

Si puede permitir una deriva de tiempo, aquí hay una solución simple que ejecuta código cada minuto:

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

Simplemente ejecute executeRepeatedly() una vez y se ejecutará cada minuto. La ejecución se detiene cuando se libera el objeto propietario ( self ). También puede usar una bandera para indicar que la ejecución debe detenerse.

    Intereting Posts