NewThe Flutter Kit — Flutter boilerplate$149$69
Swift Concurrency · 2026 Edition

async/await in Swift — Complete Guide for SwiftUI Developers

Everything you need to know about Swift concurrency in 2026 — async/await, actors, Sendable, Swift 6.2 approachable concurrency, and SwiftUI patterns.

Last updated: 2026-05-16 11 min read By Ahmed Gagan, iOS Engineer
Quick Answer

async/await is Swift\'s built-in concurrency model — async functions can suspend at await without blocking the thread, while the compiler enforces data-race safety via actors and the Sendable protocol. In 2026, prefer async/await for nearly all async work (network, file, animations, AI streaming). Combine only for genuine reactive streams. GCD only for legacy bridging. Swift 6.2\'s approachable concurrency mode lowers the learning curve for indies.

Introduced
Swift 5.5 (2021)
Hardened in
Swift 6 (2024)
Current mode (Xcode 26.3)
Approachable Concurrency by default
Min iOS for use
iOS 15+ (works back via backdeploy)

The Basics

An async function is declared with async and called with await. The compiler tracks where execution can suspend, and the runtime schedules continuations efficiently.

Basic async function
func fetchUser(id: UUID) async throws -> User {
  let (data, _) = try await URLSession.shared.data(from: userURL(id))
  return try JSONDecoder().decode(User.self, from: data)
}

// Caller:
Task {
  do {
    let user = try await fetchUser(id: currentUserID)
    print(user.name)
  } catch {
    print("Failed: \(error)")
  }
}

async/await in SwiftUI Views

The .task modifier is the SwiftUI-native way to run async work when a view appears. It auto-cancels when the view disappears.

TaskListView.swift
struct TaskListView: View {
  @State private var tasks: [Task] = []

  var body: some View {
    List(tasks) { TaskRow(task: $0) }
      .task {
        // Runs when view appears, cancels on disappear
        tasks = (try? await fetchTasks()) ?? []
      }
  }
}

Actors and Data-Race Safety

When multiple tasks access shared mutable state, you risk data races. Actors serialize access so only one task touches the state at a time.

UserCache.swift
actor UserCache {
  private var cache: [UUID: User] = [:]

  func get(_ id: UUID) -> User? {
    cache[id]
  }

  func set(_ user: User) {
    cache[user.id] = user
  }
}

// Caller — every method is implicitly async
let cache = UserCache()
await cache.set(user)
let cached = await cache.get(id)

Sendable — Compile-Time Concurrency Safety

Sendable is a marker protocol. Types that conform are safe to pass across task boundaries. Swift 6 strict mode warns when you cross a boundary with non-Sendable types.

  • All value types (struct, enum) whose members are Sendable → Sendable automatically
  • final class with let-only stored properties → can be Sendable
  • Reference types with mutable state → need @unchecked Sendable + manual locking, or use an actor
  • Closures that capture state → mark with @Sendable to verify

Task Groups for Concurrent Work

TaskGroup lets you run many async operations in parallel and collect results — without writing manual synchronization.

Parallel fetches with TaskGroup
func fetchAll(ids: [UUID]) 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
  }
}

Swift 6.2 Approachable Concurrency

Swift 6.2 (2026) introduced a less-strict concurrency mode for solo developers. In Xcode 26.3+, this is the default for new projects.

  • @MainActor isolation inferred for many UI types (less ceremony)
  • Looser Sendable checking for app code (still strict for library / framework code)
  • Better error messages for data-race warnings
  • Strict mode opt-in for teams + library authors
  • The Swift Kit ships with approachable concurrency enabled

Modern concurrency, ready to ship.

The Swift Kit is built on Swift 6.2 with approachable concurrency — async/await + @Observable + actors everywhere it matters.

Get The Swift Kit — $99

Frequently Asked Questions

What is async/await in Swift?
async/await is Swift's built-in concurrency model, introduced in Swift 5.5 (2021) and matured in Swift 6 (2024). An async function can suspend execution while waiting for a result (network call, file read, sleep) without blocking the thread. The await keyword marks suspension points. It replaces callback-based APIs (completion handlers) with linear, readable code.
How is async/await different from GCD or Combine?
GCD (DispatchQueue) is a thread-pool API — you manually move work between queues. Combine is a reactive framework for streams. async/await is structured concurrency — the compiler enforces data-race safety, manages task lifetimes, and integrates with the type system. In 2026, prefer async/await for one-shot work, Combine only for genuine reactive streams, and GCD only for legacy interop.
What's an actor in Swift?
An actor is a class-like type that protects its state from data races by serializing access. Only one task can access an actor's mutable state at a time. You call actor methods with await (because they're effectively async). Use actors for shared mutable state — caches, networking clients, state stores.
What does Sendable mean?
Sendable is a marker protocol indicating a type is safe to pass across concurrency boundaries (between tasks, across actor boundaries). Value types of Sendable members are Sendable. Reference types need explicit @unchecked Sendable or final + immutable properties. Swift 6 enforces Sendable at compile time — failures show as data-race warnings.
How do I use async/await in SwiftUI?
Use the .task modifier on views to run async work when the view appears. Use Task { ... } inside button actions for fire-and-forget work. Use async @Observable view model methods for state mutations. The view automatically re-renders when @Observable properties change.
What is Swift 6.2 approachable concurrency?
Swift 6.2 (2026) introduced "approachable concurrency" — a less-strict mode that relaxes Sendable enforcement for solo / indie developers learning concurrency. The default for new projects in Xcode 26.3+ is approachable mode. Strict mode is opt-in for teams and library authors who want maximum data-race safety.

Keep exploring

Ship your iOS app 10× faster

The Swift Kit gives you a production-ready SwiftUI boilerplate — design system, paywall, auth, AI, all pre-wired. $99 one-time.

Get The Swift Kit — $99

One-time purchase · Lifetime updates · 14-day refund