Each WWDC brings lots of new goods for all Apple ecosystem developers. The 2021 edition wasn't different. AsyncImage view is a new SwiftUI addition that expects an URL instead of an asset to display images. Read further to learn how to use it.

Displaying images from the web is a widespread task in mobile applications. You can see this in all social media applications, web-based knowledge bases, or apps that stream files from servers. It requires more work than displaying images locally. After all, we have to wait until the image is loaded (usually displaying placeholder) and handling situations where the network connection is not reliable (or the file doesn't exist anymore). AsyncView is creating to make those operations easier. When it comes to displaying images, it uses an Image view underneath.

The simplest form of AsyncView requires only the url parameter with the URL object. This url parameter is optional, so you don't have to check its existence when creating it using the URL(string:_) constructor.

let url = URL(string: "http://placekitten.com/200/200")
AsyncImage(url: url)

But often, you may want to do more with a result. One of the most common scenarios was to resize the image to fit its frame.  The AsyncImage first initializer can handle` scale` parameter and two convenient closures - content and placeholder. The first one performs operations on the Image view when it is finally loaded, and the second one returns a view displayed when an image is loading.

AsyncImage(url: url) { image in
    image.resizable()
} placeholder: {
    Text("Loading...")
}

With content closure, you can resize the image, fit it to content or apply rounded corners.

But there is a second initializer that allows for more advanced control. You will probably be using that version more often. It also supports url and scale properties, but there is a new transaction parameter, and content closure gets AsyncImagePhase enum. You can use the data provided in that enum to return a view for different phases of image loading. When the network file is loaded (success phase), you will get an Image view. For failure error is returned. There is a third empty phase which means that the file is loading. The transaction parameter is used to provide an animation applied when phases are changing.

AsyncImage(
    url: url,
    transaction: Transaction(
        animation: .easeInOut
    )
) { phase in
     if let image = phase.image {
         image.resizable()
    } else if phase.error != nil {
        Text("Error!")
    } else {
        Text("Loading...")
    }
}
AsyncImage SwiftUI Playground

Want to test it yourself? Download this Xcode playground.