Bird
Raised Fist0
iOS Swiftmobile~20 mins

Structured concurrency in iOS Swift - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Structured Concurrency Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ ui_behavior
intermediate
2:00remaining
Understanding async let behavior in Swift concurrency
What will be printed when this Swift code runs?
iOS Swift
func fetchData() async {
  async let first = fetchFirst()
  async let second = fetchSecond()
  let result1 = await first
  let result2 = await second
  print("Results: \(result1), \(result2)")
}

func fetchFirst() async -> String {
  return "First"
}

func fetchSecond() async -> String {
  return "Second"
}

Task {
  await fetchData()
}
AResults: Second, First
BResults: First, Second
CResults: nil, nil
DCompilation error due to missing await
Attempts:
2 left
💡 Hint
Remember that async let starts tasks concurrently and await waits for their results.
❓ lifecycle
intermediate
2:00remaining
Task cancellation in structured concurrency
What happens when the child task is cancelled before it completes in this Swift code?
iOS Swift
func parentTask() async throws {
  let child = Task {
    try await Task.sleep(nanoseconds: 2_000_000_000)
    print("Child finished")
  }
  try await Task.sleep(nanoseconds: 1_000_000_000)
  print("Parent cancelling child")
  child.cancel()
  print("Parent finished")
}

Task {
  try await parentTask()
}
APrints "Parent cancelling child" then "Parent finished"; "Child finished" is never printed
BPrints "Child finished" then "Parent cancelling child" then "Parent finished"
CPrints "Parent cancelling child" then "Child finished" then "Parent finished"
DCompilation error due to incorrect Task usage
Attempts:
2 left
💡 Hint
Consider what happens when a Task is cancelled before it finishes sleeping.
🧠 Conceptual
advanced
2:00remaining
Why use TaskGroup in Swift concurrency?
Which statement best explains the main advantage of using TaskGroup in Swift structured concurrency?
AIt automatically retries failed tasks without developer intervention.
BIt serializes tasks to run one after another to save memory.
CIt allows running multiple child tasks concurrently and waits for all to complete, collecting their results safely.
DIt replaces async let for single asynchronous calls.
Attempts:
2 left
💡 Hint
Think about how TaskGroup manages multiple tasks and their results.
📝 Syntax
advanced
2:00remaining
Identify the syntax error in this Swift concurrency code
Which option correctly identifies the syntax error in the following Swift code snippet?
iOS Swift
func loadData() async {
  async let data1 = fetchData1()
  let data2 = await fetchData2()
  print(await data1, data2)
}

func fetchData1() async -> String { "Data1" }
func fetchData2() async -> String { "Data2" }
AMissing await before data1 in print statement
Basync let cannot be used with fetchData1()
CfetchData2() must be called without await
Dprint statement must be inside a Task block
Attempts:
2 left
💡 Hint
Remember how to get the value from an async let binding.
🔧 Debug
expert
2:00remaining
Diagnose the cause of a deadlock in Swift structured concurrency
Given this Swift code, why does the program deadlock and never print "Done"?
iOS Swift
func deadlockExample() async {
  let task = Task {
    await deadlockExample()
  }
  await task.value
  print("Done")
}

Task {
  await deadlockExample()
}
AThe print statement is unreachable due to syntax error
BTask cannot be created inside an async function
CMissing await before task creation causes deadlock
DThe task recursively awaits itself causing infinite recursion and deadlock
Attempts:
2 left
💡 Hint
Look at the recursive call inside the Task and what it awaits.

Practice

(1/5)
1. What is the main purpose of structured concurrency in Swift's async code?
easy
A. To make synchronous code run faster
B. To organize async tasks into groups that run and finish together
C. To avoid using async/await keywords
D. To write code without any error handling

Solution

  1. Step 1: Understand structured concurrency concept

    Structured concurrency groups async tasks so they start and finish as a unit.
  2. Step 2: Compare options with concept

    Only To organize async tasks into groups that run and finish together correctly describes this grouping and coordination of async tasks.
  3. Final Answer:

    To organize async tasks into groups that run and finish together -> Option B
  4. Quick Check:

    Structured concurrency = task grouping [OK]
Hint: Structured concurrency means grouping async tasks [OK]
Common Mistakes:
  • Thinking it speeds up synchronous code
  • Confusing it with removing async/await
  • Ignoring error handling in async tasks
2. Which of the following is the correct syntax to create a task group in Swift concurrency?
easy
A. await withTaskGroup(of: Int.self) { group in ... }
B. withTaskGroup await (of: Int.self) { group in ... }
C. taskGroup await (Int) { group in ... }
D. await taskGroup(of: Int) { group in ... }

Solution

  1. Step 1: Recall correct syntax for task groups

    The correct syntax uses 'await withTaskGroup(of: Type.self) { group in ... }'.
  2. Step 2: Check each option's syntax

    Only await withTaskGroup(of: Int.self) { group in ... } matches the correct Swift syntax for task groups.
  3. Final Answer:

    await withTaskGroup(of: Int.self) { group in ... } -> Option A
  4. Quick Check:

    Correct task group syntax = await withTaskGroup(of: Int.self) { group in ... } [OK]
Hint: Remember 'await withTaskGroup(of: Type.self)' syntax [OK]
Common Mistakes:
  • Placing 'await' after 'withTaskGroup'
  • Using wrong order of keywords
  • Omitting '.self' after type
3. What will be the output of this Swift code snippet using a task group?
func fetchValues() async -> [Int] {
  await withTaskGroup(of: Int.self) { group in
    group.addTask { 10 }
    group.addTask { 20 }
    var results = [Int]()
    for await value in group {
      results.append(value)
    }
    return results.sorted()
  }
}

Task {
  let values = await fetchValues()
  print(values)
}
medium
A. Compilation error
B. [20, 10]
C. [10]
D. [10, 20]

Solution

  1. Step 1: Understand task group execution

    Two tasks return 10 and 20 concurrently; results are collected in 'results'.
  2. Step 2: Analyze result sorting and output

    Results are sorted before returning, so output is [10, 20].
  3. Final Answer:

    [10, 20] -> Option D
  4. Quick Check:

    Task group collects and sorts results [OK]
Hint: Task group results can arrive unordered; sorting fixes order [OK]
Common Mistakes:
  • Assuming order of results matches task add order
  • Forgetting to sort results
  • Expecting compilation error due to async
4. Identify the error in this Swift code using structured concurrency:
func loadData() async {
  await withTaskGroup(of: String.self) { group in
    group.addTask { "First" }
    group.addTask { "Second" }
    for value in group {
      print(value)
    }
  }
}
medium
A. Incorrect type specified in withTaskGroup
B. group.addTask syntax is invalid
C. Missing 'await' before 'for' loop to iterate group
D. No error, code is correct

Solution

  1. Step 1: Check iteration over task group

    Iterating over a task group requires 'for await' to await each task's result.
  2. Step 2: Identify missing 'await' keyword

    The code uses 'for value in group' instead of 'for await value in group', causing error.
  3. Final Answer:

    Missing 'await' before 'for' loop to iterate group -> Option C
  4. Quick Check:

    Use 'for await' to iterate async task groups [OK]
Hint: Use 'for await' to loop over async task groups [OK]
Common Mistakes:
  • Using 'for' instead of 'for await' on task groups
  • Confusing task group type with task return type
  • Misusing addTask syntax
5. You want to fetch data from multiple URLs concurrently and combine their results safely. Which approach best uses structured concurrency in Swift?
hard
A. Use 'await withTaskGroup' to add a task for each URL fetch, then collect and combine results
B. Create multiple detached tasks without waiting, then combine results later
C. Fetch URLs one by one synchronously in a loop
D. Use DispatchQueue.global().async without task groups

Solution

  1. Step 1: Understand structured concurrency for multiple async tasks

    Using 'await withTaskGroup' allows running multiple async tasks concurrently and safely collecting results.
  2. Step 2: Compare approaches for concurrency and safety

    Use 'await withTaskGroup' to add a task for each URL fetch, then collect and combine results uses task groups correctly; others either run tasks unsafely or synchronously.
  3. Final Answer:

    Use 'await withTaskGroup' to add a task for each URL fetch, then collect and combine results -> Option A
  4. Quick Check:

    Task groups = safe concurrent task management [OK]
Hint: Use task groups to run and gather multiple async tasks safely [OK]
Common Mistakes:
  • Using detached tasks without waiting causes race conditions
  • Fetching synchronously loses concurrency benefits
  • Using DispatchQueue without structured concurrency loses safety
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