You all might know that async/await is accepted and is available in the main snapshots! Let’s get our hands dirty by trying out some basic example of async/await in Swift.

Prerequisites

  1. Xcode 12.3
  2. Latest Swift Toolchain (You can download it from here)

Installing the Swift Toolchain

Download the Swift Toolchain, and install the .pkg file. After installing the Swift toolchain, open Xcode and go to Preferences -> Components and select Swift Development Snapshot

Swift Development Toolchain

Next, go to your Project’s build settings and add the following Swift flags -Xfrontend -enable-experimental-concurrency

Swift Compiler Flags

That’s it! You have installed the latest Swift Development Toolchain in your Xcode.

Using completion handlers to handle asynchronous tasks

We usually use completion handlers for handling asynchronous tasks. For example,

private func getPlayerNames(completion: (() -> Void)? = nil) {
    DispatchQueue.global().async {
        self.playerNames = self.gamePlayers.map {
            return $0.name
        }
        completion?()
    }
}

internal func performCompletionHandlerCall() { 
	self.getPlayerNames {
        print("Printing names from a completion handler ", self.playerNames)
    }
}

The above code is OK, but there are too many things going on. It is error-prone, and the code starts falling apart when nesting of multiple completion handlers is required, which eventually leads to the pyramid of doom. Let’s find out how to re-write the above code using the new async await approach.

Replacing completion handlers with async/await

When you write async/await code, the boilerplate code is reduced, and it allows us to focus on improving the performance of the concurrent code.

private func refreshPlayers() async {
    self.playerNames = await self.getNames()
}

private func getNames() async -> [String] {
    return self.gamePlayers.map{$0.name}
}

@asyncHandler internal func performAsyncAwaitOperation() {
    await self.refreshPlayers()
    print("Printing names from a async await function ", playerNames)
}

The above code is clean, precise, self explanatory, and less confusing. The usage of async and await keywords in the methods improve the readability of the code.

Closing Thoughts

The async/await pattern is a vast improvement. The real power of async/await will be revealed when multiple asynchronous operations are chained. It is still in development, and many more improvements are made as we speak. I will be keeping an eye on how things shape, and I will be writing more articles about the async/await pattern. If you are interested in learning more about the async/await pattern, I have given reference links at the end of the article. You can give it a read for a better understanding. Also, I have uploaded the demo project to github. You can download it from here.

References

[1] https://forums.swift.org/t/swift-concurrency-roadmap/41611

[2] https://forums.swift.org/t/question-about-async-await/6659/15

[3] https://forums.swift.org/t/concurrency-fixing-race-conditions-in-async-await-example/6514/45

Special mentions

Shoutout to Karthikeyan for his help in setting up the toolchain and stuff.

App Showcase

Winya - A free screen-sharing app that casts your screen to Twitch in HD. It will be useful for gamers to streaming their gameplay to Twitch. Ohmyswifters, download the app and show your support to them.

iOS, and iPadOS download link