Adam Rush

@Adam9Rush

22 February, 2022

Introduction

Suppose you’re a seasoned developer on the iOS platform. In that case, you’ll remember the struggles of downloading an image from a URL, making sure it’s on the background thread, updating the ImageView on the main thread, then ensuring it’s cached and stored correctly and performantly.

It’s no surprise that within SwiftUI, we have this functionality right out of the box with the AsyncImage() API. It was introduced in 2021 and is iOS15+.

AsyncImage()

Under the hood, AsyncImage() uses URLSession and handles all the logic internally.

struct ContentView: View {
    var body: some View {
        AsyncImage(url: URL(string: "https://usercontent.one/wp/www.swiftlyrush.com/wp-content/uploads/2021/11/image-2.png?media=1637150467"))
    }
}

You can create an AsyncImage() like your above example, and you’re downloading a face that you might be familiar with ;]. In your example, you will make a profile picture with rounded corners.

You can now see that the image is downloading, but it’s a square image with the default shape.

struct ContentView: View {
    var body: some View {
        AsyncImage(url: URL(string: "https://usercontent.one/wp/www.swiftlyrush.com/wp-content/uploads/2021/11/image-2.png?media=1637150467"))
            .clipShape(Circle())
    }
}

You can use the .clipShape(Circle()) modifier to clip the profile image into a perfectly formatted circle.

An iPhone 13 using the AsycImage in SwiftUI

Placeholder

You will notice that the image has a grey background colour when downloading, and Apple has introduced a placeholder parameter that can be used when creating an AsyncImage(). In your example, you will add a loading spinner to show that the image is currently downloading.

struct ContentView: View {
    var body: some View {
        AsyncImage(url: URL(string: "https://usercontent.one/wp/www.swiftlyrush.com/wp-content/uploads/2021/11/image-2.png?media=1637150467"), content: { image in
            image.resizable()
        }, placeholder: {
            ProgressView()
        })
            .frame(width: 100, height: 100)
            .clipShape(Circle())
    }
}

To take advantage of the placeholder parameter, you also need to deal with the content of the downloaded image; this is because you’re essentially swapping the placeholder for the downloaded image.

In your example, you’re getting a brand new ProgressView(), the placeholder and then calling resizable() on the downloaded image so that it correctly resizes to 100px wide and 100px in height.

It’s that simple, and you can change the placeholder to anything you wish. It could also be a static image or even a placeholder image used across your application.

Where Next?

You can see how easy it is to download an image safely from the internet using AsyncImage(). You can read more about using ProgressView’s here.

Why not try to incorporate AsyncImage within your iOS application?

Sponsor

Subscribe for curated Swift content for free

- weekly delivered.