TaskGroup: Dynamic, Structured Concurrency in Swift

A TaskGroup is like a manager for parallel jobs. You add a dynamic number of tasks, and it runs them concurrently, ensuring the parent task waits for them all. Use it to fetch multiple images or API data.
WHY IT EXISTS: Modern applications often need to perform an unknown number of operations at the same time, like fetching multiple resources from a network. Managing this manually is complex and error-prone. TaskGroup provides a high-level, safe abstraction for this exact scenario within Swift's structured concurrency model.
THE MENTAL MODEL: Think of a TaskGroup as a temporary, self-contained workspace for running parallel jobs. You open the group, add any number of jobs (child tasks), and the group ensures the parent task doesn't continue until all its children have completed, successfully or not. It brings order to dynamic parallelism.
HOW IT WORKS: You create a group using the withTaskGroup function. Inside its closure, you receive a group parameter that you use to add new concurrent work with the addTask method. You can then use a for await loop on the group to collect results as they become available, or simply let the withTaskGroup scope end, which implicitly awaits all child tasks.
WHEN TO USE IT: Use a TaskGroup when you need to run a variable number of similar, independent tasks concurrently. A classic use case is fetching a list of images where the count isn't known at compile time, or processing chunks of a large data file in parallel.
WHEN NOT TO USE IT: If you have a fixed, small number of different tasks, using async let is simpler and more readable. For example, fetching a user's profile and their settings from two separate endpoints. TaskGroup is overkill for that fixed-size workload. Also, do not use it for tasks that need to outlive the current function scope; use an unstructured Task for that.
ONE CANONICAL EXAMPLE: To fetch data for a list of user IDs, you can create a TaskGroup, loop through your IDs, and call group.addTask for each one to kick off a network request. You can then use for await result in group to collect user data as each request finishes. A key feature is that if one network request throws an error, the entire group is automatically cancelled, stopping redundant work.
Read the original → developer.apple.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.