📖 Scenario: You are building a simple Swift program that fetches user data and user posts asynchronously. You want to use Swift's structured concurrency model to run these tasks concurrently and then combine their results.
🎯 Goal: Learn how to use Swift's async and await keywords along with async let to run concurrent tasks in a structured way.
📋 What You'll Learn
Create two asynchronous functions: fetchUserData() and fetchUserPosts()
Use async let to run both functions concurrently
Await both results and combine them into a single string
Print the combined result
💡 Why This Matters
🌍 Real World
Structured concurrency helps write clean and safe asynchronous code, such as fetching data from multiple sources at the same time in apps.
💼 Career
Understanding Swift's structured concurrency is essential for iOS developers working on modern apps that require efficient and readable asynchronous code.
Progress0 / 4 steps
1
Create asynchronous functions to fetch data
Write two asynchronous functions called fetchUserData() and fetchUserPosts(). Each function should return a String after a short delay. fetchUserData() should return "User Data" and fetchUserPosts() should return "User Posts".
Swift
Hint
Use async keyword in function signature and Task.sleep(nanoseconds:) to simulate delay.
2
Set up async let bindings to run tasks concurrently
Inside an asynchronous main() function, use async let to start fetchUserData() and fetchUserPosts() concurrently. Name the bindings userData and userPosts respectively.
Swift
Hint
Use async let to start both functions concurrently inside main().
3
Await both async let bindings and combine results
Inside the main() function, await both userData and userPosts and combine their results into a single string variable called combinedResult. The combined string should be in the format: "User Data + User Posts".
Swift
Hint
Use await to get the results from userData and userPosts and combine them with string interpolation.
4
Print the combined result
Add a print statement inside the main() function to display the combinedResult string.
Swift
Hint
Use print(combinedResult) to show the final combined string.
Practice
(1/5)
1. What is the main purpose of structured concurrency in Swift?
easy
A. To group tasks so they run safely and complete before continuing
B. To allow tasks to run forever without waiting
C. To make tasks run only on the main thread
D. To avoid using async and await keywords
Solution
Step 1: Understand structured concurrency concept
Structured concurrency groups related tasks so they run safely and finish before the program moves on.
Step 2: Compare options with concept
Only To group tasks so they run safely and complete before continuing correctly describes grouping tasks to run safely and complete before continuing.
Final Answer:
To group tasks so they run safely and complete before continuing -> Option A
Quick Check:
Structured concurrency = safe grouped tasks [OK]
Hint: Structured concurrency means tasks finish before moving on [OK]
Common Mistakes:
Thinking tasks run forever without waiting
Believing tasks only run on main thread
Confusing structured concurrency with avoiding async/await
2. Which of the following is the correct syntax to create a task group in Swift?
easy
A. withTaskGroup(of: Int.self) { group in ... }
B. asyncGroup { ... }
C. taskGroup.run { ... }
D. TaskGroup { await ... }
Solution
Step 1: Recall correct task group syntax
Swift uses withTaskGroup(of: Type.self) { group in ... } to create a task group.
Step 2: Check options for exact syntax
Only withTaskGroup(of: Int.self) { group in ... } matches the correct syntax; others are invalid or made-up.
Final Answer:
withTaskGroup(of: Int.self) { group in ... } -> Option A
Quick Check:
Task group syntax = withTaskGroup(of:) [OK]
Hint: Task groups start with withTaskGroup(of:) [OK]
Common Mistakes:
Using TaskGroup without 'with'
Trying taskGroup.run which doesn't exist
Using asyncGroup which is not a Swift keyword
3. What will be the output of this Swift code using a task group?
func fetchValues() async -> [Int] {
await withTaskGroup(of: Int.self) { group in
group.addTask { 3 }
group.addTask { 7 }
group.addTask { 2 }
var results = [Int]()
for await value in group {
results.append(value)
}
return results.sorted()
}
}
Task {
let values = await fetchValues()
print(values)
}
medium
A. [3, 7, 2]
B. [2, 3, 7]
C. [7, 3, 2]
D. Compilation error
Solution
Step 1: Understand task group execution
The tasks return 3, 7, and 2 asynchronously. The for-await loop collects them in any order.
Step 2: Analyze the return statement
The results array is sorted before returning, so output is sorted ascending: [2, 3, 7].
Final Answer:
[2, 3, 7] -> Option B
Quick Check:
Sorted results = [2, 3, 7] [OK]
Hint: Remember results are sorted before printing [OK]
Common Mistakes:
Assuming tasks run in order added
Forgetting the sorting step
Thinking code causes compile error
4. Identify the error in this Swift code using a task group:
func calculateSum() async -> Int {
await withTaskGroup(of: Int.self) { group in
group.addTask { 10 }
group.addTask { 20 }
var total = 0
for value in group {
total += value
}
return total
}
}
medium
A. Return type should be Void
B. Cannot add tasks inside withTaskGroup
C. Missing 'await' before 'for' loop
D. Variable 'total' should be declared outside the group
Solution
Step 1: Check for correct async iteration
When iterating over a task group, 'for await' must be used to await each task's result.
Step 2: Identify missing 'await'
The code uses 'for value in group' instead of 'for await value in group', causing a syntax error.
Final Answer:
Missing 'await' before 'for' loop -> Option C
Quick Check:
Async iteration requires 'for await' [OK]
Hint: Use 'for await' to loop over task groups [OK]
Common Mistakes:
Using 'for' instead of 'for await' on task groups
Thinking tasks can't be added inside withTaskGroup
Misunderstanding return type requirements
5. You want to fetch user data and user posts concurrently using structured concurrency. Which approach correctly uses a task group to run both tasks and combine their results?
hard
A. Use DispatchQueue.global().async to run tasks and wait with sleep()
B. Run tasks sequentially without a task group to avoid concurrency issues
C. Create two separate Task blocks and return results without waiting
D. Use withTaskGroup to add two tasks fetching data and posts, then await all and return combined tuple
Solution
Step 1: Understand concurrency for multiple async tasks
Structured concurrency uses task groups to run multiple async tasks concurrently and wait for all to finish.
Step 2: Evaluate options for correct concurrency usage
Use withTaskGroup to add two tasks fetching data and posts, then await all and return combined tuple correctly uses withTaskGroup to add tasks, await their completion, and combine results safely.
Final Answer:
Use withTaskGroup to add two tasks fetching data and posts, then await all and return combined tuple -> Option D
Quick Check:
Task groups run and wait for multiple tasks [OK]
Hint: Use withTaskGroup to run and wait multiple tasks [OK]