Search code examples
swiftswift5foundationwwdc

Asynchronously iterating line-by-line through a file


In the "Platforms State of the Union" video of WWDC2021 at 28:00 it was mentioned that

[Apple] even added support for asynchronously iterating line-by-line through a file

in Foundation for macOS 12/iOS 15 and Swift 5.5.

What is that new API, how can I now asynchronously iterate line-by-line through a file?


Solution

  • The main thing they added that enables this, is AsyncSequence. AsyncSequence is like Sequence, but its Iterator.next method is async throws.

    Specifically, you can use URLSession.AsyncBytes.lines to get an AsyncSequence of the lines in a file.

    Suppose you are in an async throws method, you can do:

    let (bytes, response) = try await URLSession.shared.bytes(from: URL(string: "file://...")!)
    for try await line in bytes.lines {
        // do something...
    }
    

    Note that there is also FileHandle.AsyncBytes.lines, but in the documentation it says:

    Rather than creating a FileHandle to read a file asynchronously, you can instead use a file:// URL in combination with the async-await methods in URLSession. These include the bytes(for:delegate:) and bytes(from:delegate:) methods that deliver an asynchronous sequence of bytes, and data(for:delegate:) and data(from:delegate:) to return the file’s entire contents at once.