Bird
Raised Fist0
Swiftprogramming~20 mins

Task groups for parallel execution in Swift - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Swift Task Group Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of concurrent task group with async sleeps
What is the output of this Swift code using task groups for parallel execution?
Swift
import Foundation

func testTaskGroup() async {
    await withThrowingTaskGroup(of: String.self) { group in
        group.addTask {
            try await Task.sleep(nanoseconds: 1_000_000_000)
            return "First"
        }
        group.addTask {
            try await Task.sleep(nanoseconds: 500_000_000)
            return "Second"
        }
        group.addTask {
            return "Third"
        }

        for try await result in group {
            print(result)
        }
    }}

Task {
    await testTaskGroup()
}
RunLoop.main.run()
A
Third
First
Second
B
First
Second
Third
C
Second
Third
First
D
Third
Second
First
Attempts:
2 left
💡 Hint
Remember that tasks in a task group complete independently and results are received as they finish.
🧠 Conceptual
intermediate
1:30remaining
Understanding task group cancellation behavior
In Swift concurrency, what happens to remaining tasks in a task group if one task throws an error?
AOnly the task that threw the error is cancelled; others continue.
BAll remaining tasks are immediately cancelled and the error is propagated.
CThe task group waits for all tasks to finish before propagating the error.
DRemaining tasks continue running and the error is ignored.
Attempts:
2 left
💡 Hint
Think about how Swift handles errors in concurrent task groups to avoid wasted work.
🔧 Debug
advanced
2:00remaining
Identify the error in this task group code
What error does this Swift code produce?
Swift
import Foundation

func runTasks() async throws {
    await withThrowingTaskGroup(of: Int.self) { group in
        for i in 1...3 {
            group.addTask {
                if i == 2 {
                    throw NSError(domain: "Test", code: 1)
                }
                return i
            }
        }

        for try await value in group {
            print(value)
        }
    }}

Task {
    do {
        try await runTasks()
    } catch {
        print("Error: \(error)")
    }
}
RunLoop.main.run()
ARuntime error: Task group throws and cancels remaining tasks
BCompilation error: 'throw' used in non-throwing closure
CNo error; prints 1 and 3
DDeadlock because tasks wait on each other
Attempts:
2 left
💡 Hint
Check if the closure passed to addTask supports throwing errors.
📝 Syntax
advanced
1:30remaining
Correct syntax for adding tasks with return values in a task group
Which option shows the correct syntax to add tasks returning Int values in a Swift task group?
Swift
await withTaskGroup(of: Int.self) { group in
    // Add tasks here
}
Agroup.addTask(async { 5 })
Bgroup.addTask { await 5 }
Cgroup.addTask { return 5 }
Dgroup.addTask { throw 5 }
Attempts:
2 left
💡 Hint
Remember the closure passed to addTask can be async but does not require 'await' for returning a value.
🚀 Application
expert
2:30remaining
Calculate sum of squares using task groups concurrently
Given this Swift code, what is the value of 'total' after execution?
Swift
import Foundation

func sumOfSquares(_ numbers: [Int]) async -> Int {
    await withTaskGroup(of: Int.self) { group in
        for number in numbers {
            group.addTask {
                number * number
            }
        }

        var sum = 0
        for await value in group {
            sum += value
        }
        return sum
    }
}

Task {
    let total = await sumOfSquares([1, 2, 3, 4])
    print(total)
}
RunLoop.main.run()
A30
B20
C10
D25
Attempts:
2 left
💡 Hint
Calculate each number squared and add them all: 1² + 2² + 3² + 4².

Practice

(1/5)
1. What is the main purpose of using a TaskGroup in Swift concurrency?
easy
A. To run multiple tasks in parallel and wait for all to complete
B. To create a single long-running task
C. To pause the current task indefinitely
D. To handle errors in synchronous code

Solution

  1. Step 1: Understand what TaskGroup does

    A TaskGroup lets you run many tasks at the same time, managing them together.
  2. Step 2: Identify the main use

    It allows parallel execution and waits until all tasks finish before continuing.
  3. Final Answer:

    To run multiple tasks in parallel and wait for all to complete -> Option A
  4. Quick Check:

    TaskGroup = parallel tasks + wait [OK]
Hint: TaskGroup runs tasks together and waits for all [OK]
Common Mistakes:
  • Thinking TaskGroup runs only one task
  • Confusing TaskGroup with error handling
  • Assuming TaskGroup pauses tasks
2. Which of the following is the correct way to add a task inside a TaskGroup in Swift?
easy
A. group.runTask(fetchData())
B. group.createTask(fetchData)
C. group.addTask { await fetchData() }
D. group.startTask { fetchData() }

Solution

  1. Step 1: Recall the method to add tasks

    The correct method to add a task is addTask with a closure.
  2. Step 2: Check syntax correctness

    group.addTask { await fetchData() } uses group.addTask { await fetchData() }, which is the right syntax.
  3. Final Answer:

    group.addTask { await fetchData() } -> Option C
  4. Quick Check:

    Use addTask with closure [OK]
Hint: Use addTask with closure to add work [OK]
Common Mistakes:
  • Using wrong method names like runTask or createTask
  • Not using closure syntax
  • Omitting await inside the task
3. What will be the output of this Swift code using a TaskGroup?
func fetchNumber(_ n: Int) async -> Int {
    return n * 2
}

func runGroup() async {
    await withTaskGroup(of: Int.self) { group in
        for i in 1...3 {
            group.addTask { await fetchNumber(i) }
        }
        var results = [Int]()
        for await result in group {
            results.append(result)
        }
        print(results.sorted())
    }
}

Task {
    await runGroup()
}
medium
A. Compilation error
B. [1, 2, 3]
C. [6, 4, 2]
D. [2, 4, 6]

Solution

  1. Step 1: Understand the task group adds tasks for numbers 1 to 3

    Each task returns the input number multiplied by 2: 2, 4, and 6.
  2. Step 2: Collect results and sort them before printing

    Results are collected in any order but sorted before printing, so output is [2, 4, 6].
  3. Final Answer:

    [2, 4, 6] -> Option D
  4. Quick Check:

    Results doubled and sorted = [2,4,6] [OK]
Hint: Remember to sort results after parallel tasks [OK]
Common Mistakes:
  • Assuming results print in order added
  • Forgetting to await inside addTask
  • Confusing output with original numbers
4. Identify the error in this Swift code using a TaskGroup:
await withTaskGroup(of: Int.self) { group in
    for i in 1...3 {
        group.addTask { fetchNumber(i) }
    }
    for await result in group {
        print(result)
    }
}
Assuming fetchNumber is an async function.
medium
A. Missing await inside addTask closure
B. Cannot use for await with TaskGroup
C. TaskGroup must be declared with var
D. fetchNumber must return Void

Solution

  1. Step 1: Check how fetchNumber is called inside addTask

    fetchNumber is async, so it must be awaited inside the closure.
  2. Step 2: Identify missing await keyword

    The closure calls fetchNumber(i) without await, causing a compile error.
  3. Final Answer:

    Missing await inside addTask closure -> Option A
  4. Quick Check:

    Async calls inside addTask need await [OK]
Hint: Always await async calls inside addTask closures [OK]
Common Mistakes:
  • Forgetting await inside addTask
  • Thinking for await can't be used with TaskGroup
  • Declaring TaskGroup incorrectly
5. You want to fetch data from multiple URLs in parallel using a TaskGroup and collect only the successful results (non-nil). Which approach correctly filters out nil results while running tasks in parallel?
hard
A. Run tasks sequentially inside the group to avoid nil results
B. Add tasks returning optional data, then filter non-nil in for await loop
C. Use addTask with throwing function and catch errors outside group
D. Use withThrowingTaskGroup but ignore errors and collect all results

Solution

  1. Step 1: Understand the goal to run tasks in parallel and filter nil

    Running tasks in parallel with TaskGroup allows concurrency; filtering nil after collecting results is straightforward.
  2. Step 2: Evaluate options for filtering nil results

    Add tasks returning optional data, then filter non-nil in for await loop correctly adds tasks returning optional data and filters non-nil results in the for await loop, matching the goal.
  3. Final Answer:

    Add tasks returning optional data, then filter non-nil in for await loop -> Option B
  4. Quick Check:

    Filter nil after parallel tasks with for await [OK]
Hint: Filter nil results after collecting parallel task outputs [OK]
Common Mistakes:
  • Trying to run tasks sequentially losing parallelism
  • Ignoring errors without filtering nil
  • Misusing throwing task groups for simple filtering
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