Swift Concurrency: Async and Await Made Easy

Swift Concurrency: Async and Await Made Easy Swift Concurrency: Async and Await Made Easy

Introduction: When you use apps, sometimes the app needs to download something from the internet. If the app stops working while downloading, the user will think the app is frozen. We use Concurrency to keep the app smooth. Today, let's understand async and await using very easy words.

The Bank Teller Analogy (What is Thread Blocking?)

Imagine a bank with only **one teller** (this is like your app's **Main Thread**). The teller does two things:

  • Task 1: Help customers deposit money (fast UI updates, like button taps).
  • Task 2: Go to the backroom to search for old document files (slow task, like downloading an image).

If a customer asks for an old file, and the teller walks to the backroom to search for it, the counter is empty. Other customers waiting in line cannot do anything. The bank is **blocked**.

But if the teller says: 'I will send a helper to search the backroom. Please wait on the side, and I will help the next person in line.' Now, the line keeps moving. That helper is a **background thread**, and the process is **Asynchronous**.

In iOS, the Main Thread is the bank teller. Slow tasks must be sent to the background so your app does not freeze.

How async and await Work

Swift makes this very simple with two keywords:

  • async: Put this next to a function name to say: 'This function does slow work, run it in the background.'
  • await: Put this when you call that function to say: 'Wait here until the work is done, but let the main thread keep working on other things.'

Code Example: Downloading Data Safely

Let's write a simple Swift code to download text from a website. We will also handle errors (like when internet is off) using try and catch.

swift
import Foundation

// 1. Mark the function as async and throws (can throw errors)
func fetchUserMessage() async throws -> String {
    let url = URL(string: "https://api.example.com/message")!
    
    // Use await: download in background without blocking UI
    let (data, _) = try await URLSession.shared.data(from: url)
    
    if let message = String(data: data, encoding: .utf8) {
        return message
    } else {
        throw NSError(domain: "InvalidData", code: 0)
    }
}

// 2. How to call it safely inside a Task
Task {
    do {
        let message = try await fetchUserMessage()
        print("Received: \(message)")
    } catch {
        print("Oops, download failed: \(error.localizedDescription)")
    }
}
By using try await, the code is safe and easy to read. It reads like normal step-by-step code, but it runs asynchronously behind the scenes.

Summary

Swift Concurrency keeps your app responsive. Use async to mark slow tasks, and await to wait for them without blocking the main screen. Combined with try-catch, it is the safest way to download data.

 All Articles
Share: