async-await in swift
Disclaimer — This is less of an article and more of a note that I have created after reading “async-await” articles and watching “Meet async-await in Swift” WWDC 21 video.
Hopefully this will clarify some of the doubts that you have regarding “async-await in Swift”. So, lets get straight into the topic.
Note — I am planning to write more on this topic and this article will be update accordingly in the future.
— — — — — — — — — — — — — — — — — —
Synchronous function
A synchronous function is one that executes all its work in a simple, straight line on a single thread.
Example
Problem
- Synchronous function calls are blocking calls.
Asynchronous functions
Types
1. Asynchronous functions with completion handlers
2. Asynchronous functions with delegation call-backs e.g. Location APIs delegates
3. Asynchronous functions marked with async keyword — New in Swift 5.5
Example of an asynchronous function with async keyword
func fetchImage(for id: String) async -> UIImage
Asynchronous functions with completion handlers
//Fetching an image over the network and then converting it into a thumbnail and returning it
Problem — Swift can’t check our work
- Can’t enforce invocation of completion handlers for all possible cases — It’s very easy to forgot calling the completion handler and In Swift there is no way to enforce that a completion handler is always invoked.
- Can’t use swift’s usual error handling mechanism — A synchronous function can either return a value or throw an error and swift ensures that if a value is not returned an error is thrown. But we can’t just throw an error from a completion handler.
async — await to the rescue
//Fetching an image over the network and then converting it into a thumbnail and returning it
Syntax — Things to notice
- When you mark a function as async, the keyword should go just before “throws” in the function signature, i.e. just before the arrow if the function doesn’t throw.
- “try” is here because the data method is marked “throws”.
- Just as try is needed to call a function marked as throws, await is need to call a function marked as async.
What async keyword indicates?
- A function marked async is allowed to be suspended and when it suspends itself then it suspends its callers too, so callers must be async too.
What await keyword indicates?
- Await keyword is used to point out where in an async function it might suspend.
Throwing function analogy
- While an async function may suspend, just because it marked as async doesn’t necessarily mean it will suspend, just like a function marked as throws doesn’t mean that it will always through an error, it may or may not throw.
- Similarly, just because await is mentioned doesn’t mean function will definitely suspend there, just like using a “try” keyword just before calling a function that can throw an error.
Synchronous vs async — Difference in the control flow
Synchronous calls
Image Source — https://developer.apple.com/videos/play/wwdc2021/10132/
Async calls
Image Source — https://developer.apple.com/videos/play/wwdc2021/10132/
Important points
- Async function can suspend as many times as it needs to
- While an async function may suspend, just because it marked as async doesn’t necessarily mean it will suspend.
- Similarly, just because await is mentioned doesn’t mean function will definitely suspend there.
- But eventually whether an async function suspends or not, after finishing it will return the control of the thread to the calling function along with a value or error.
- A function may resume onto an entirely different thread.
Another async-await control flow example
async properties and initializers
- Not just functions but properties can be async too and so can initializers.
Things to notice
- Only read-only properties can be async
- Property getters can also throw
If an expression has multiple async function calls, you only need to write await once, just like you only need one “try” for an expression with multiple throwing calls.
URLSession — Syntax comparison between completion handler vs async-await versions
Completion handler version
Declared under NSURLSession Category (Objective — c)
async-await version
Declared under URLSession extension
Things to notice
- In the async version, no need to add “resume()” to invoke a data task.
- async version returns non-optional data and response and in case of failure it throws an exception which makes it lot easier to handle at the call site as now there is no need to add extra logic to handle optional data or error.
XCTest supports async
Testing an asynchronous methods — completion handler approach.
Testing an asynchronous method — async-await approach
Things to notice
- In the async version, no need to set an expectation for an asynchronous function.
Xcode — 13 Tip
- Xcode 13 has a new option to convert an asynchronous function with completion handler approach to an asynchronous function with async-await approach.
- CMD + left click on an asynchronous function with completion handler approach with present the conversion option.
Result after conversion
Conclusion
That’s it for now, thanks for reading. Also if you really find this helpful then please leave some applause to this article.😀😀😀