0
0
Swiftprogramming~5 mins

Structured concurrency model in Swift

Choose your learning style9 modes available
Introduction

Structured concurrency helps you write clear and safe code that runs tasks at the same time. It keeps tasks organized so you don't lose track of them.

When you want to run multiple tasks at once but keep them easy to manage.
When you need to wait for several tasks to finish before moving on.
When you want to avoid bugs from tasks running without control.
When you want your program to stop all related tasks if one fails.
When you want your code to be easier to read and understand.
Syntax
Swift
func example() async {
    await withTaskGroup(of: Void.self) { group in
        group.addTask {
            // task 1 work
        }
        group.addTask {
            // task 2 work
        }
        // wait for all tasks to finish
    }
}

withTaskGroup creates a group to run tasks together.

Tasks inside the group run concurrently but are managed as one unit.

Examples
This example runs two tasks that return strings and prints each result as it arrives.
Swift
func fetchImages() async {
    await withTaskGroup(of: String.self) { group in
        group.addTask { "Image 1" }
        group.addTask { "Image 2" }

        for await image in group {
            print("Got: \(image)")
        }
    }
}
This example shows how to handle tasks that can throw errors inside a throwing task group.
Swift
func downloadFiles() async throws {
    try await withThrowingTaskGroup(of: Data.self) { group in
        group.addTask { try downloadFile(url: url1) }
        group.addTask { try downloadFile(url: url2) }

        for try await fileData in group {
            print("Downloaded file with size: \(fileData.count)")
        }
    }
}
Sample Program

This program runs two tasks concurrently to fetch user data and prints each piece as it arrives.

Swift
import Foundation

func fetchUserData() async {
    await withTaskGroup(of: String.self) { group in
        group.addTask {
            // Simulate fetching user name
            "Alice"
        }
        group.addTask {
            // Simulate fetching user city
            "Wonderland"
        }

        for await data in group {
            print("Received: \(data)")
        }
    }
}

@main
struct Main {
    static func main() async {
        await fetchUserData()
    }
}
OutputSuccess
Important Notes

Structured concurrency makes sure all tasks finish or cancel together.

Use withTaskGroup for simple tasks and withThrowingTaskGroup if tasks can fail.

Tasks inside groups run concurrently but are easier to control and debug.

Summary

Structured concurrency groups tasks to run together safely.

It helps keep your code clean and avoids lost or runaway tasks.

Use task groups to run and wait for multiple tasks easily.