Coding With Amit
← Back to Articles

Understanding Swift async/await

Amit Sen

iOS engineer and educator. Helping developers build real-world skills.

Introduction

Swift's async/await makes asynchronous code readable and maintainable. In this post, we'll explore the basics and common patterns.

Why async/await?

Before async/await, we used completion handlers and callbacks. The result was often "callback hell" — nested closures that were hard to follow.

With async/await, you write async code that looks like synchronous code:

func fetchUser() async throws -> User {
    let data = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data.0)
}

Key Concepts

  • async — Marks a function that can suspend
  • await — Suspends until the async operation completes
  • Task — Creates a new async context

Error Handling

do {
    let user = try await fetchUser()
    print(user.name)
} catch {
    print("Failed to fetch: \(error)")
}

Next Steps

  1. Convert your completion-handler code to async/await
  2. Learn about actors for thread-safe state
  3. Explore structured concurrency with TaskGroup

Want to go deeper? Check out our Swift Concurrency course.

Understanding Swift async/await | Coding With Amit