AsyncSequence and AsyncStreamThese are the lesson notes for this day. Its build-along tutorial and flash cards have not been written yet.
AsyncSequence and AsyncStreamAn AsyncSequence delivers values over time. You consume one with for await value in sequence. Many system APIs provide one, such as URLSession.bytes and NotificationCenter.notifications. AsyncStream lets you build your own from code that uses callbacks: you are given a continuation, and you call yield on it each time the old API calls back. Swift 6.4 adds a safer Continuation type for wrapping an API that calls back exactly once.
The open-source Swift Async Algorithms package adds operators such as debounce, throttle, merge and combineLatest. One limitation is worth knowing: an async sequence is normally consumed by a single for await loop. It does not broadcast to several listeners.
func ticks(from ticker: Ticker) -> AsyncStream<Int> {
AsyncStream { continuation in
ticker.onTick = { count in
continuation.yield(count) // each callback becomes a value
}
continuation.onTermination = { _ in ticker.stop() }
ticker.start()
}
}
// Consumed like any sequence: for await count in ticks(from: ticker) { ... }
Exercise
Wrap a delegate-based API you know well — location updates, a timer, keyboard notifications — in an AsyncStream, and consume it with for await inside a .task.
AsyncSequence?for await loop come to an end?