Tasks let your app do work in the background without freezing the screen. TaskGroups help you run many tasks together and wait for all to finish.
When you want to download several images at the same time without stopping the app.
When you need to fetch data from multiple sources and combine the results.
When you want to perform several calculations in parallel to speed up your app.
When you want to run background work but still update the UI when done.
Syntax
iOS Swift
Task {
// code to run asynchronously
}
await withTaskGroup(of: ReturnType.self) { group in
group.addTask {
// first async task
}
group.addTask {
// second async task
}
forawait result in group {
// handle each result
}
}
Use Task to start one asynchronous job.
Use withTaskGroup to run many tasks together and wait for all results.
Examples
This runs a simple task that prints a message without blocking the main thread.
iOS Swift
Task {
print("Hello from a task!")
}
This runs two tasks in parallel that add numbers, then prints each result as they finish.
iOS Swift
await withTaskGroup(of: Int.self) { group in
group.addTask { 1 + 1 }
group.addTask { 2 + 2 }
forawait value in group {
print("Result: \(value)")
}
}
Sample App
This SwiftUI app has a button that starts three tasks in parallel. Each task does a simple math calculation. When all finish, the results show in a list.
iOS Swift
import SwiftUI
struct ContentView: View {
@State private var results: [Int] = []
var body: some View {
VStack(spacing: 20) {
Button("Start Tasks") {
Task {
await runTasks()
}
}
List(results, id: \.self) { result in
Text("Result: \(result)")
}
}
.padding()
}
func runTasks() async {
var tempResults: [Int] = []
await withTaskGroup(of: Int.self) { group in
group.addTask { 10 * 2 }
group.addTask { 5 + 5 }
group.addTask { 3 * 7 }
forawait value in group {
tempResults.append(value)
}
}
results = tempResults
}
}
OutputSuccess
Important Notes
Tasks run asynchronously, so the app stays responsive.
withTaskGroup waits for all tasks to finish before continuing.
Use await to pause until a task or group finishes.
Summary
Task runs one background job.
withTaskGroup runs many jobs together and collects results.
Use these to keep your app smooth and fast.
Practice
(1/5)
1. What is the main purpose of a Task in Swift concurrency?
easy
A. To run a single background job asynchronously
B. To group multiple tasks and run them together
C. To update the UI on the main thread
D. To pause the app execution
Solution
Step 1: Understand what Task does
A Task is designed to run one asynchronous job in the background.
Step 2: Differentiate from TaskGroup
TaskGroup runs many jobs together, not a single job.
Final Answer:
To run a single background job asynchronously -> Option A
Quick Check:
Task = single background job [OK]
Hint: Task runs one job; TaskGroup runs many [OK]
Common Mistakes:
Confusing Task with TaskGroup
Thinking Task updates UI directly
Assuming Task pauses app execution
2. Which of the following is the correct syntax to create a Task that prints "Hello" asynchronously?
easy
A. async Task { print("Hello") }
B. TaskGroup { print("Hello") }
C. Task.run { print("Hello") }
D. Task { print("Hello") }
Solution
Step 1: Recall correct Task syntax
The correct way to create a Task is using Task { ... } with a closure.
Step 2: Check other options for errors
TaskGroup is not used like this; async Task and Task.run are invalid syntax.
Hint: Use Task { } with closure for async code [OK]
Common Mistakes:
Using TaskGroup instead of Task
Adding 'async' keyword before Task
Trying to call Task.run which doesn't exist
3. What will be printed by this Swift code using TaskGroup?
func fetchData() async {
await withTaskGroup(of: String.self) { group in
group.addTask { "A" }
group.addTask { "B" }
for await result in group {
print(result)
}
}
}
fetchData()
medium
A. Either A then B or B then A (order not guaranteed)
B. B then A in order
C. A then B in order
D. No output because of syntax error
Solution
Step 1: Understand TaskGroup concurrency
TaskGroup runs tasks concurrently and collects results as they finish, order is not guaranteed.
Step 2: Analyze the code output
Since tasks return "A" and "B" concurrently, the print order can be either "A" then "B" or "B" then "A".
Final Answer:
Either A then B or B then A (order not guaranteed) -> Option A
Quick Check:
TaskGroup results order is unpredictable [OK]
Hint: TaskGroup runs tasks concurrently; output order varies [OK]
Common Mistakes:
Assuming TaskGroup results are always ordered
Thinking tasks run sequentially
Believing syntax error prevents output
4. Identify the error in this Swift code using TaskGroup:
await withTaskGroup(of: Int.self) { group in
group.addTask { 1 }
group.addTask { 2 }
for result in group {
print(result)
}
}
medium
A. Incorrect type in 'withTaskGroup' declaration
B. Using 'for' instead of 'for await' to iterate the group
C. Missing 'await' before 'for' loop
D. Cannot add tasks inside 'withTaskGroup'
Solution
Step 1: Check iteration over TaskGroup
Iteration over a TaskGroup is asynchronous, so it requires for await.
Step 2: Identify the error in the code
The code uses for result in group without await, causing a compile error.
Final Answer:
Using 'for' instead of 'for await' to iterate the group -> Option B
Quick Check:
Async iteration needs 'for await' [OK]
Hint: Use 'for await' to loop over TaskGroup results [OK]
Common Mistakes:
Forgetting 'await' in asynchronous loops
Confusing TaskGroup type declaration
Thinking tasks can't be added inside withTaskGroup
5. You want to fetch user data from three different servers concurrently and combine the results. Which Swift concurrency pattern using TaskGroup is best to achieve this?
hard
A. Create three separate Task instances and wait for each sequentially
B. Run three synchronous functions one after another on the main thread
C. Use a TaskGroup to add three tasks fetching data, then collect all results asynchronously
D. Use a single Task that fetches data from all servers sequentially
Solution
Step 1: Understand concurrency needs
Fetching from three servers concurrently requires running tasks in parallel to save time.
Step 2: Choose the best Swift concurrency pattern
TaskGroup allows adding multiple tasks and collecting results asynchronously, perfect for this use case.
Final Answer:
Use a TaskGroup to add three tasks fetching data, then collect all results asynchronously -> Option C
Quick Check:
TaskGroup = concurrent multiple tasks [OK]
Hint: Use TaskGroup for multiple concurrent tasks and results [OK]