Bird
Raised Fist0
Swiftprogramming~20 mins

Async sequences (AsyncSequence) in Swift - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Async Sequence Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this async sequence code?
Consider the following Swift code using an async sequence. What will be printed when this code runs?
Swift
import Foundation

struct Countdown: AsyncSequence {
    typealias Element = Int
    let start: Int

    struct AsyncIterator: AsyncIteratorProtocol {
        var current: Int

        mutating func next() async -> Int? {
            if current < 0 {
                return nil
            } else {
                let value = current
                current -= 1
                return value
            }
        }
    }

    func makeAsyncIterator() -> AsyncIterator {
        AsyncIterator(current: start)
    }
}

@main
struct Main {
    static func main() async {
        let countdown = Countdown(start: 3)
        var result = ""
        for await number in countdown {
            result += "\(number) "
        }
        print(result.trimmingCharacters(in: .whitespaces))
    }
}
A"3 2 1 0 -1"
B"4 3 2 1 0"
C"0 1 2 3"
D"3 2 1 0"
Attempts:
2 left
💡 Hint
Think about how the iterator decreases the current value and when it stops.
🧠 Conceptual
intermediate
1:30remaining
Which statement about AsyncSequence is true?
Choose the correct statement about AsyncSequence in Swift.
AAsyncSequence allows iteration over values asynchronously using for await-in loops.
BAsyncSequence requires implementing a synchronous iterator method called makeIterator().
CAsyncSequence can only be used with arrays and dictionaries.
DAsyncSequence does not support throwing errors during iteration.
Attempts:
2 left
💡 Hint
Think about how async sequences are consumed in Swift.
🔧 Debug
advanced
2:00remaining
What error does this async sequence code produce?
This Swift code attempts to create an async sequence but has a problem. What error will it cause?
Swift
struct Numbers: AsyncSequence {
    typealias Element = Int

    func makeAsyncIterator() -> some AsyncIteratorProtocol {
        return Iterator()
    }

    struct Iterator: AsyncIteratorProtocol {
        var current = 0

        mutating func next() async -> Int? {
            if current < 3 {
                defer { current += 1 }
                return current
            } else {
                return nil
            }
        }
    }
}
ACompile-time error: 'current' used in mutating context but 'next()' is not mutating
BRuntime error: Infinite loop due to never returning nil
CCompile-time error: Missing async keyword on makeAsyncIterator()
DNo error, code runs correctly
Attempts:
2 left
💡 Hint
Check if the method that changes state is marked mutating.
📝 Syntax
advanced
1:30remaining
Which option correctly defines an async iterator's next() method?
Select the correct syntax for the next() method in an AsyncIteratorProtocol conforming struct.
Amutating func next() -> Element? async { ... }
Bfunc next() -> Element? async { ... }
Cmutating func next() async -> Element? { ... }
Dfunc next() async throws -> Element? { ... }
Attempts:
2 left
💡 Hint
Remember the order of async and throws keywords in Swift function declarations.
🚀 Application
expert
2:30remaining
How many items does this async sequence produce?
Given this async sequence, how many elements will be produced when iterated fully?
Swift
struct EvenNumbers: AsyncSequence {
    typealias Element = Int
    let max: Int

    struct Iterator: AsyncIteratorProtocol {
        var current = 0
        let max: Int

        mutating func next() async -> Int? {
            if current > max {
                return nil
            }
            let result = current
            current += 2
            return result
        }
    }

    func makeAsyncIterator() -> Iterator {
        Iterator(current: 0, max: max)
    }
}

@main
struct Main {
    static func main() async {
        let evens = EvenNumbers(max: 7)
        var count = 0
        for await _ in evens {
            count += 1
        }
        print(count)
    }
}
A5
B4
C7
D3
Attempts:
2 left
💡 Hint
Count even numbers from 0 up to and including max.

Practice

(1/5)
1. What is the main purpose of using AsyncSequence in Swift?
easy
A. To create synchronous loops that block until completion
B. To define static arrays with fixed values
C. To handle streams of values that arrive over time without blocking the program
D. To perform immediate calculations without delay

Solution

  1. Step 1: Understand AsyncSequence purpose

    AsyncSequence is designed to handle values that come asynchronously over time, like events or data streams.
  2. Step 2: Compare options with AsyncSequence use

    Only To handle streams of values that arrive over time without blocking the program correctly describes handling streams without blocking, which is the key feature of AsyncSequence.
  3. Final Answer:

    To handle streams of values that arrive over time without blocking the program -> Option C
  4. Quick Check:

    AsyncSequence = handle async streams [OK]
Hint: AsyncSequence handles values arriving over time without blocking [OK]
Common Mistakes:
  • Confusing AsyncSequence with synchronous loops
  • Thinking AsyncSequence is for static data
  • Assuming it blocks program execution
2. Which of the following is the correct syntax to iterate over an AsyncSequence named numbers?
easy
A. for await number in numbers { print(number) }
B. for number in numbers { print(number) }
C. while let number = numbers.next() { print(number) }
D. numbers.forEach { print($0) }

Solution

  1. Step 1: Recall AsyncSequence iteration syntax

    AsyncSequence requires asynchronous iteration using for await to wait for values.
  2. Step 2: Check each option

    for await number in numbers { print(number) } uses for await, which is correct. for number in numbers { print(number) } is synchronous, C is invalid syntax for AsyncSequence, and D is not supported.
  3. Final Answer:

    for await number in numbers { print(number) } -> Option A
  4. Quick Check:

    AsyncSequence loops use for await [OK]
Hint: Use 'for await' to loop over AsyncSequence values [OK]
Common Mistakes:
  • Using regular for loop without await
  • Trying to call next() synchronously
  • Using forEach which is not async-compatible
3. What will be printed by the following Swift code?
struct Counter: AsyncSequence {
  typealias Element = Int
  struct AsyncIterator: AsyncIteratorProtocol {
    var count = 1
    mutating func next() async -> Int? {
      guard count <= 3 else { return nil }
      defer { count += 1 }
      return count
    }
  }
  func makeAsyncIterator() -> AsyncIterator {
    AsyncIterator()
  }
}

let counter = Counter()
Task {
  for await number in counter {
    print(number)
  }
}
medium
A. 1 2 3
B. 0 1 2
C. 1 2 3 4
D. No output, code will not compile

Solution

  1. Step 1: Analyze AsyncIterator next() method

    The iterator returns count starting at 1, increments after returning, and stops after 3.
  2. Step 2: Trace iteration values

    Values returned are 1, then 2, then 3, then nil to end the loop.
  3. Final Answer:

    1 2 3 -> Option A
  4. Quick Check:

    AsyncSequence yields 1,2,3 then ends [OK]
Hint: Check next() return and guard condition carefully [OK]
Common Mistakes:
  • Assuming count starts at 0
  • Forgetting defer increments count after return
  • Expecting 4 as output
4. Identify the error in this AsyncSequence implementation:
struct SimpleAsync: AsyncSequence {
  typealias Element = String
  struct AsyncIterator: AsyncIteratorProtocol {
    func next() async -> String? {
      return "Hello"
    }
  }
  func makeAsyncIterator() -> AsyncIterator {
    AsyncIterator()
  }
}
medium
A. makeAsyncIterator() must be async
B. next() should be mutating to update state
C. AsyncIterator must be a class, not a struct
D. Element type cannot be String

Solution

  1. Step 1: Understand AsyncIteratorProtocol requirements

    The next() method often needs to update internal state, so it must be marked mutating in a struct.
  2. Step 2: Check the code's next() method

    Here, next() is not mutating but returns a constant string repeatedly, which is incorrect for iteration.
  3. Final Answer:

    next() should be mutating to update state -> Option B
  4. Quick Check:

    next() mutating required in struct iterator [OK]
Hint: next() in struct iterator must be mutating if state changes [OK]
Common Mistakes:
  • Thinking AsyncIterator must be a class
  • Making makeAsyncIterator async unnecessarily
  • Believing String cannot be Element type
5. You want to create an AsyncSequence that emits only even numbers from 2 to 10 inclusive. Which implementation correctly achieves this?
hard
A. struct EvenNumbers: AsyncSequence { typealias Element = Int struct AsyncIterator: AsyncIteratorProtocol { var current = 2 mutating func next() async -> Int? { guard current < 10 else { return nil } defer { current += 2 } return current } } func makeAsyncIterator() -> AsyncIterator { AsyncIterator() } }
B. struct EvenNumbers: AsyncSequence { typealias Element = Int struct AsyncIterator: AsyncIteratorProtocol { var current = 1 mutating func next() async -> Int? { guard current <= 10 else { return nil } defer { current += 1 } return current * 2 } } func makeAsyncIterator() -> AsyncIterator { AsyncIterator() } }
C. struct EvenNumbers: AsyncSequence { typealias Element = Int struct AsyncIterator: AsyncIteratorProtocol { var current = 0 mutating func next() async -> Int? { guard current <= 10 else { return nil } current += 2 return current } } func makeAsyncIterator() -> AsyncIterator { AsyncIterator() } }
D. struct EvenNumbers: AsyncSequence { typealias Element = Int struct AsyncIterator: AsyncIteratorProtocol { var current = 2 mutating func next() async -> Int? { if current > 10 { return nil } let result = current current += 2 return result } } func makeAsyncIterator() -> AsyncIterator { AsyncIterator() } }

Solution

  1. Step 1: Identify required sequence

    Even numbers from 2 to 10 inclusive: 2, 4, 6, 8, 10 exactly.
  2. Step 2: Trace execution of each

    A (< 10, defer +=2): 2,4,6,8 (stops at current=10). Misses 10.
    B (*2 on odds): 2,4,6,8,10,12,... overshoots.
    C (<=10, +=2 first): 2,4,6,8,10,12 extra.
    D (if >10 nil, result first): 2,4,6,8,10 perfect.
  3. Final Answer:

    if current > 10 { return nil }
    let result = current
    current += 2
    return result
    -> Option D
  4. Quick Check:

    Only D emits exactly 2,4,6,8,10 [OK]
Hint: Return current before increment; stop when current > 10 [OK]
Common Mistakes:
  • Incrementing before returning causing off-by-one errors
  • Incorrect guard conditions excluding last value
  • Multiplying inside next() causing wrong sequence
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard