Two words you can use for cleaner code

the Swift logo on a yellow background

We can now use async and await to help write cleaner code with Swift 5.5

Released as part of Swift 5.5, async and await are 2 keywords that help you to write cleaner asynchronous code. Where we used to need completion handlers to process the results of something like an API call, now we can use these new keywords.

async is the keyword to mark a function as asynchronous. This tells the compiler that it needs to be called in a certain way.

await is the keyword for calling an async function.

To give a short example:

Before

func getPage(pageId: Int, callback: (Result<Page, Error>) -> Void) {
 // Perform API call
}

getPage(pageId: 1) { result in
 switch result {
 case .success(page):
 break
 case .failure(error):
 break
 }
}

After

func getPage(pageId: Int) async throws {
 // Perform API call
}

do {
 let page = try await getPage(pageId: 1)
} catch {

}

Although the benefits may not be obvious from such a simple example, they become clearer when you need to chain multiple asynchronous calls together.

// Callbacks
doSomething() { result1 in
 doSomethingElse() { result2 in
 doAnotherThing() { result3 in
 // Use result1, result2, and result3
 }
 }
}

// async/await
let result1 = await doSomething()
let result2 = await doSomethingElse()
let result3 = await doAnotherThing()

Adding error handling to the example above would emphasise it even more. It’s also worth noting that not all async functions need to be marked as throws, and therefore don’t need to be called in a do...catch block. Depending on your use case you may prefer to return an optional value instead, or maybe you can return a default value instead.

Calling async functions in parallel

In the example above, we called 3 async functions but we did them one at a time. It’s possible to be more efficient but allowing them to happen in parallel can speed up execution. To do this, we can define the let statements as async and then await later

async let result1 = doSomething()
async let result2 = doSomethingElse()
async let result3 = doAnotherThing()
await [result1, result2, result3]

Tasks, Actors and more

The Swift concurrency suite offers much more functionality, including Tasks (a block of code run asynchronously) and Actors (a way of sharing data between concurrent code). The official Swift docs provide more details on these.

Click here to read more about how Brightec have been using Swift in our mobile app development process.


Looking for something else?

Search over 400 blog posts from our team

Want to hear more?

Subscribe to our monthly digest of blogs to stay in the loop and come with us on our journey to make things better!