SyntaxStudy
Sign Up
Swift Beginner 1 min read

Async/Await

Swift 5.5 introduced structured concurrency with async/await. Asynchronous functions are marked async and called with await. The call suspends the current task without blocking the thread. Async sequences and async streams allow for-await-in loops over asynchronous data. Task and TaskGroup manage concurrent work with automatic cancellation propagation. The actor type protects mutable state from data races — only one task can access actor state at a time, with await required for cross-actor calls.
Example
import Foundation

// Async function
func fetchData(from url: URL) async throws -> Data {
    let (data, response) = try await URLSession.shared.data(from: url)
    guard let http = response as? HTTPURLResponse, http.statusCode == 200 else {
        throw URLError(.badServerResponse)
    }
    return data
}

// Calling async functions
func loadUserProfile(id: Int) async throws -> User {
    let url = URL(string: "https://api.example.com/users/\(id)")!
    let data = try await fetchData(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Concurrent execution with async let
func loadDashboard() async throws {
    async let user = loadUserProfile(id: 1)
    async let posts = fetchPosts()
    let (u, p) = try await (user, posts)
    print("Loaded \(u) with \(p.count) posts")
}

// Task
Task {
    do {
        try await loadDashboard()
    } catch {
        print("Error: \(error)")
    }
}

// Actor for thread-safe state
actor BankAccount {
    private var balance: Double = 0

    func deposit(_ amount: Double) { balance += amount }
    func withdraw(_ amount: Double) -> Bool {
        guard balance >= amount else { return false }
        balance -= amount
        return true
    }
    func getBalance() -> Double { balance }
}