tezvyn:

AsyncSequence: A Sequence That Awaits Its Next Element

AI-drafted, machine-checkedSource: developer.apple.comintermediate
AsyncSequence: A Sequence That Awaits Its Next Element

AsyncSequence is like a regular Swift Sequence, but you `await` its next element. It lets you process values that arrive over time, like network data, without blocking. The footgun: iteration suspends, so run it in a `Task` for true concurrency.

WHY IT EXISTS: Before Swift concurrency, processing asynchronous streams of data required complex patterns like Combine publishers or nested completion handlers. AsyncSequence was created to provide a structured, linear way to handle these events using the natural for await in loop syntax, making asynchronous code read like synchronous code.

THE MENTAL MODEL: An AsyncSequence is like a regular Swift Sequence (e.g., an Array), but you await its next element. Imagine a conveyor belt where items appear at unpredictable intervals. A for await in loop is like a worker who waits for an item to arrive, processes it, and then waits for the next one, without holding up the entire factory.

HOW IT WORKS: An AsyncSequence provides an AsyncIterator. The for await in loop calls the iterator's next() method, which is marked async. This method can suspend execution until a value is available. When a value is produced, next() returns it. When the sequence is finished, next() returns nil, and the loop terminates. This allows the thread to perform other work while waiting.

WHEN TO USE IT: Use AsyncSequence for any series of values produced over time. It's ideal for reading a large file line-by-line (URL.lines), receiving data chunks from a network request (URLSession.bytes), or observing system notifications (NotificationCenter.notifications(named:)). It dramatically simplifies code that would otherwise rely on delegates or callbacks.

WHEN NOT TO USE IT: Avoid AsyncSequence for collections that are already fully loaded in memory. For a simple Array of data, a standard for in loop is more direct and performant. Using AsyncSequence for synchronous data adds unnecessary concurrency overhead without any benefit.

ONE CANONICAL EXAMPLE: To read a text file line by line without loading the entire file into memory, URL.lines provides an AsyncSequence. You can iterate through it with: for await line in someURL.lines { print(line) }. This loop suspends while waiting for the next line to be read from disk, processes it, and then repeats, keeping memory usage low and the app responsive.

Read the original → developer.apple.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.