Is async await a replacement for Combine

In this blog post I want to explore the idea "Is async/await a replacement for Combine in Swift".

Posted By Adam Bulmer In Swift

On Twitter, I recently saw this meme make the rounds. Whilst it did make me smile because who doesn't like a bit of Green Arrow/Flash banter. I started to wonder why their is a common belief that async/await replaces Combine.

Async Await Combine Grant Gustin Meme

What is Combine

Apple provides Combine, an API built on top of the standard Swift language. Combine is used to process values over time like user input. This is sometimes known as "reactive programming". Combine is modelled on the idea of Publishers and Subscribers which receive values over time from Publishers.

[1,2,3,4].publisher.map {
    return $0 * 10
}
.debounce(for: 1, scheduler: DispatchQueue.main)
.sink { value in
    print(value)
}

It's called Combine because you can combine the output of multiple publishers and use them as inputs to other publishers. I find it's sometimes useful to visualise this as merging drainage pipes underground.

Marble Diagram

What is Async/Await

Async/await is a newer language feature of Swift introduced at WWDC21. It enables you to handle concurrency in Swift enabling better performance for your apps. This is because asynchronous code can be suspended and resumed allowing the app UI to be updated whilst working on long-running operations like fetching data over the network.

The API for async/await is similar to the API you may be familiar with if you have written modern JavaScript code before. We call it async/await because async is short for asynchronous and is an attribute you add to the return type of a method to inform the compiler that the method will perform an asynchronous action. The await attribute is used when calling our async methods.

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

func fetchBestPokemon() async throws -> NSDictionary {
    let url = URL(string: "https://pokeapi.co/api/v2/pokemon/charmander")!
    let (data, _) = try await URLSession.shared.data(for: URLRequest(url: url))

    return try JSONSerialization.jsonObject(with: data) as! NSDictionary

}

Task.init {
    let response = try await fetchBestPokemon()
    print(response["name"])
}

When a async/await method is called a value is returned at some-point in the future and will only return the value once. Repeated calls to the async methods are required if you want to continuously retrieve the latest version of a value.

Which tool when?

Combine should be used anytime you want to observe a value over time such as user gestures or an event elsewhere in your app like a user switching themes. You may also be using Combine depending on if you're using SwiftUI. SwiftUI makes use of Combine when using @Published, @StateObject and @ObservedObject property wrappers.

Async/await is useful when a task is going to take time to complete and you don't want your application to be blocked. This is useful when your application is working on long-running tasks like network requests or parsing files.

Subscribe To The Newsletter

If you want to create your first native app or have just begun your native app development journey, be sure to sign up to the newsletter. No Spam