Tickers in Swift

Our example demonstrates the use of tickers, which are used for repeatedly performing actions at regular intervals. Here’s how we can implement this in Swift:

import Foundation

func main() {
    // Tickers use a similar mechanism to timers: a
    // DispatchSourceTimer that fires at regular intervals.
    // Here we'll use a DispatchQueue to handle the values
    // as they arrive every 500ms.
    let queue = DispatchQueue(label: "tickerQueue")
    let timer = DispatchSource.makeTimerSource(queue: queue)
    
    timer.schedule(deadline: .now(), repeating: .milliseconds(500))
    
    let semaphore = DispatchSemaphore(value: 0)
    
    timer.setEventHandler {
        let now = Date()
        print("Tick at", now)
    }
    
    timer.resume()
    
    // Tickers can be stopped like timers. Once a ticker
    // is stopped it won't receive any more values.
    // We'll stop ours after 1600ms.
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.6) {
        timer.cancel()
        print("Ticker stopped")
        semaphore.signal()
    }
    
    semaphore.wait()
}

main()

When we run this program, the ticker should tick 3 times before we stop it.

$ swift tickers.swift
Tick at 2023-05-24 15:30:00 +0000
Tick at 2023-05-24 15:30:00 +0000
Tick at 2023-05-24 15:30:01 +0000
Ticker stopped

In this Swift version:

  1. We use DispatchSource.makeTimerSource() to create a timer that acts as our ticker.
  2. The timer is scheduled to fire every 500 milliseconds.
  3. We use a DispatchSemaphore to keep the main thread alive until we’re done.
  4. The timer’s event handler prints the current time for each tick.
  5. We use DispatchQueue.main.asyncAfter() to stop the timer after 1.6 seconds.
  6. Finally, we signal the semaphore to allow the program to exit.

This approach provides similar functionality to the original example, adapting to Swift’s concurrency model and timer mechanisms.