Swift Concurrency (async/await) Cheat Sheet
Explains Swift's async/await, structured concurrency with Task and TaskGroup, actors, and async sequences for safe concurrent code.
2 PagesAdvancedApr 2, 2026
Async Functions
Declaring and calling asynchronous functions.
swift
// Declaring an async functionfunc fetchUser(id: String) async throws -> User { let url = URL(string: "https://api.example.com/users/\(id)")! let (data, _) = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(User.self, from: data)}// Calling itTask { do { let user = try await fetchUser(id: "42") print(user.name) } catch { print("Failed: \(error)") }}
Creating Tasks
Running concurrent work with async let and unstructured tasks.
swift
// Launch concurrent work with async letasync let user = fetchUser(id: "1")async let posts = fetchPosts(userId: "1")let (u, p) = try await (user, posts) // both run concurrently// Unstructured tasklet task = Task { try await fetchUser(id: "2")}let result = try await task.value// Task with priority and cancellationlet bgTask = Task(priority: .background) { try Task.checkCancellation() return try await fetchUser(id: "3")}bgTask.cancel()
Actors & Concurrency Concepts
Core building blocks of Swift's structured concurrency model.
- actor- Reference type that serializes access to its mutable state, preventing data races
- @MainActor- Global actor that confines a type, function, or property to the main thread, e.g. for UI updates
- TaskGroup- withTaskGroup(of:) runs a dynamic number of child tasks concurrently and collects their results
- Sendable- Protocol marking types safe to pass across concurrency domains without introducing data races
- Task.sleep- try await Task.sleep(for: .seconds(1)) suspends the current task without blocking the thread
- Task.isCancelled- Cooperative cancellation flag checked inside long-running async work to exit early
Actors & Async Sequences
Defining an actor and consuming data concurrently.
swift
actor Counter { private var value = 0 func increment() -> Int { value += 1 return value }}// Reading a network response line by line with AsyncSequencefunc printLines(from url: URL) async throws { let (bytes, _) = try await URLSession.shared.bytes(from: url) for try await line in bytes.lines { print(line) }}// Concurrent fan-out with a throwing task groupfunc fetchAll(ids: [String]) async throws -> [User] { try await withThrowingTaskGroup(of: User.self) { group in for id in ids { group.addTask { try await fetchUser(id: id) } } var users: [User] = [] for try await user in group { users.append(user) } return users }}
Pro Tip
Mark shared mutable state as an actor instead of guarding it with locks — the compiler enforces safe, isolated access at compile time via async checks, catching data races before they ship.
Was this cheat sheet helpful?
Explore Topics
#SwiftConcurrencyAsyncAwait#SwiftConcurrencyAsyncAwaitCheatSheet#Programming#Advanced#AsyncFunctions#CreatingTasks#ActorsConcurrencyConcepts#ActorsAsyncSequences#Concurrency#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech
Professional Web Designing Services
- Responsive Websites
- E-commerce Solutions
- SEO Friendly Design
- Fast & Secure
- Support & Maintenance