Daniel's working notes

Meet async await in Swift

To create an async function, you can prefix with async keyword before return value

Before using async/await, we need several technique to perform asynchronous task such as completion handler, delegates, notifications etc. Common code is like this:

func fetchThumbnail(for id: String, completion: @escaping (Result<UIImage, Error>) -> Void) {
    let request = thumbnailURLRequest(for: id)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(.failure(error))
        } else if (response as? HTTPURLResponse)?.statusCode != 200 {
            completion(.failure(FetchError.badID))
        } else {
            guard let image = UIImage(data: data!) else {
                completion(.failure(FetchError.badImage))
                return
            }
            image.prepareThumbnail(of: CGSize(width: 40, height: 40)) { thumbnail in
                guard let thumbnail = thumbnail else {
                    completion(.failure(FetchError.badImage))
                    return
                }
                completion(.success(thumbnail))
            }
        }
    }
    task.resume()
}

With async/await, we can write straight line code like this one below.

func fetchThumbnail(for id: String) async throws -> UIImage {
    let request = thumbnailURLRequest(for: id)  
    let (data, response) = try await URLSession.shared.data(for: request)
    guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badID }
    let maybeImage = UIImage(data: data)
    guard let thumbnail = await maybeImage?.thumbnail else { throw FetchError.badImage }
    return thumbnail
}

async keyword not only applied for function but also properties and intializers

On properties, only read-only property can be marked async

Few notes about async/await:

  1. When we mark function as async, we’re allowing it to suspends and thus suspends the caller too so it needs to be marked with async to
  2. system can suspend the function many times, so that’s why the await keyword is used
  3. the system can schedule other work while the function is suspended. even task that’s kicked off later can be performed first than your function.

Linked Notes: