Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Diagnose and fix Swift Concurrency issues: async/await, actor isolation, Sendable, and Swift 6 migration.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/async-await-basics.md
1# Async/Await Basics23Use this when:45- You are starting fresh with async/await and need foundational patterns.6- You are converting callback-based code to async/await.7- You need to understand execution order and the sync-to-async bridge.89Skip this file if:1011- You need parallel execution with task groups or `async let`. Use `tasks.md`.12- You need stream-based async iteration. Use `async-sequences.md`.1314Jump to:1516- Function Declaration17- Execution Order18- Parallel Execution with async let19- URLSession with Async/Await20- Migration Strategy2122## Function Declaration2324Mark functions with `async` to indicate asynchronous work:2526```swift27func fetchData() async -> Data {28// async work29}3031func fetchData() async throws -> Data {32// async work that can fail33}34```3536**Key benefit over closures**: The compiler enforces return values. No forgotten completion handlers.3738> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.1: Introduction to async/await syntax](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)3940## Calling Async Functions4142### From synchronous context4344Use `Task` to bridge from sync to async:4546```swift47Task {48let data = try await fetchData()49}50```5152### From async context5354Use `await` directly:5556```swift57func processData() async throws {58let data = try await fetchData()59// process data60}61```6263## Execution Order6465Structured concurrency executes top-to-bottom in the order you expect:6667```swift68let first = try await fetchData(1) // Waits for completion69let second = try await fetchData(2) // Starts after first completes70let third = try await fetchData(3) // Starts after second completes71```7273Code after `await` only executes once the awaited function returns.7475> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.2: Understanding the order of execution](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)7677## Parallel Execution with async let7879Use `async let` to run multiple operations concurrently:8081```swift82async let data1 = fetchData(1)83async let data2 = fetchData(2)84async let data3 = fetchData(3)8586let results = try await [data1, data2, data3]87```8889### How async let works9091- **Starts immediately**: The function executes right away, even before `await`92- **Structured concurrency**: Automatically canceled when leaving scope93- **Error handling**: If one fails, others are implicitly canceled when awaiting grouped results94- **No redundant keywords**: Don't use `try await` in the `async let` line itself9596```swift97// Redundant - avoid this98async let data = try await fetchData()99100// Correct - errors handled at await point101async let data = fetchData()102let result = try await data103```104105### When to use async let106107**Use when:**108- Tasks don't depend on each other109- Number of tasks known at compile-time110- Want automatic cancellation on scope exit111112**Avoid when:**113- Tasks must run sequentially114- Need dynamic task spawning (use `TaskGroup`)115- Need manual cancellation control116117### Limitations118119- Cannot use at top-level declarations (only within function bodies)120- Tasks not explicitly awaited may be canceled implicitly121122> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.3: Calling async functions in parallel using async let](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)123124## URLSession with Async/Await125126URLSession provides async alternatives to closure-based APIs:127128```swift129// Closure-based (old)130URLSession.shared.dataTask(with: request) { data, response, error in131guard let data = data, error == nil else { return }132// handle response133}.resume()134135// Async/await (modern)136let (data, response) = try await URLSession.shared.data(for: request)137```138139### Benefits over closures140141- No optional `data` or `response` to unwrap142- Automatic error throwing143- Compiler enforces return values144- Simpler error handling with do-catch145146### Complete network request pattern147148```swift149func fetchUser(id: Int) async throws -> User {150let url = URL(string: "https://api.example.com/users/\(id)")!151var request = URLRequest(url: url)152request.httpMethod = "GET"153154let (data, response) = try await URLSession.shared.data(for: request)155156guard let httpResponse = response as? HTTPURLResponse,157(200...299).contains(httpResponse.statusCode) else {158throw NetworkError.invalidResponse159}160161return try JSONDecoder().decode(User.self, from: data)162}163```164165### POST requests with JSON166167```swift168func createUser(_ user: User) async throws -> User {169let url = URL(string: "https://api.example.com/users")!170var request = URLRequest(url: url)171request.httpMethod = "POST"172request.setValue("application/json", forHTTPHeaderField: "Content-Type")173request.httpBody = try JSONEncoder().encode(user)174175let (data, response) = try await URLSession.shared.data(for: request)176177guard let httpResponse = response as? HTTPURLResponse,178(200...299).contains(httpResponse.statusCode) else {179throw NetworkError.invalidResponse180}181182return try JSONDecoder().decode(User.self, from: data)183}184```185186> **Course Deep Dive**: This topic is covered in detail in [Lesson 2.4: Performing network requests using URLSession and async/await](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)187188## Typed Errors (Swift 6)189190Specify exact error types for better API contracts:191192```swift193enum NetworkError: Error {194case invalidResponse195case decodingFailed(DecodingError)196case requestFailed(URLError)197}198199func fetchData() async throws(NetworkError) -> Data {200do {201let (data, _) = try await URLSession.shared.data(from: url)202return data203} catch let error as URLError {204throw .requestFailed(error)205} catch {206throw .invalidResponse207}208}209```210211Callers know exactly which errors to handle.212213## Migration Strategy214215When converting closure-based code:2162171. **Add new async method alongside old one** - keeps code compiling2182. **Update method signature** - add `async`, remove completion parameter2193. **Replace closure calls with await** - use URLSession async APIs2204. **Remove optional unwrapping** - async APIs return non-optional values2215. **Simplify error handling** - use do-catch instead of nested closures2226. **Return directly** - compiler enforces return values223224## Common Patterns225226### Sequential execution (when order matters)227228```swift229let user = try await fetchUser(id: 1)230let posts = try await fetchPosts(userId: user.id)231let comments = try await fetchComments(postIds: posts.map(\.id))232```233234### Parallel execution (when independent)235236```swift237async let user = fetchUser(id: 1)238async let settings = fetchSettings()239async let notifications = fetchNotifications()240241let (userData, settingsData, notificationsData) = try await (user, settings, notifications)242```243244### Mixed execution245246```swift247// Fetch user first (required for next step)248let user = try await fetchUser(id: 1)249250// Then fetch related data in parallel251async let posts = fetchPosts(userId: user.id)252async let followers = fetchFollowers(userId: user.id)253async let following = fetchFollowing(userId: user.id)254255let profile = Profile(256user: user,257posts: try await posts,258followers: try await followers,259following: try await following260)261```262263## Further Learning264265For in-depth coverage of async/await patterns, error handling strategies, and real-world migration scenarios, see [Swift Concurrency Course](https://www.swiftconcurrencycourse.com).266267