How to Use AsyncImage in SwiftUI

AsyncLearn
3 min readJun 10, 2024

--

Image with text: How to use AsyncImage in SwiftUI | AsynLearn

AsyncImage is a SwiftUI view that allows us to asynchronously load an image. Let's see how:

import SwiftUI

struct ContentView: View {
private let url = URL(string: "https://pbs.twimg.com/profile_images/1717013664954499072/2dcJ0Unw_400x400.png")

var body: some View {
// 1
AsyncImage(url: url)
}
}

We initialize the AsyncImage view by passing the image URL as a parameter. If the URL is malformed or the request fails, a default placeholder image will be shown.

Example of an asynchronously loaded image

Example of an asynchronously loaded image

By default, AsyncImage renders the image based on its original size, meaning it doesn't resize or adjust the image. To change the size of the image, we'll use the initializer AsyncImage(url: <URL>, content: <(Image) -> View>, placeholder: <() -> View>). Let's see how:

import SwiftUI

struct ContentView: View {
private let url = URL(string: "https://pbs.twimg.com/profile_images/1717013664954499072/2dcJ0Unw_400x400.png")

var body: some View {
AsyncImage(url: url) { image in
// 1
image
.resizable()
.frame(width: 100, height: 100)
.clipShape(Circle())
} placeholder: {
// 2
ProgressView()
.padding()
.frame(width: 100, height: 100)
.background(Color.gray.opacity(0.7))
.clipShape(Circle())
}
}
}
  1. Here we have an Image view, so we can use all the Image modifiers, such as resizable(), and adjust the image size by changing the frame.
Example of an asynchronously loaded image with AsynImage, resized
  1. Here we can edit the placeholder, which is the view that will appear while the image is loading or if the image download request fails.
Example of a Placeholder using AsyncImage

Handling Errors in Image Download

If there is an error in the request, the placeholder will be shown. This can be confusing, as we might think the image is still loading. To handle this, we will use another initializer that gives us an AsyncImagePhase, which has 3 states:

  • .success(Image): Indicates that the download was successful, and we use it to display and edit the image as we did in the previous example.
  • .failure(Error): Indicates that there was an error downloading the image.
  • .empty: Indicates that the image has not yet been loaded, where we can show our ProgressView.

Let’s see how to handle errors:

import SwiftUI

struct ContentView: View {
private let url = URL(string: "https://pbs.twimg.com/profile_images/1717013664954499072/2dcJ0Unw_400x400.png")

var body: some View {
AsyncImage(url: url) { phase in
switch phase {
case .success(let image):
image
.resizable()
.frame(width: 100, height: 100)
.clipShape(Circle())
case .empty:
ProgressView()
.padding()
.frame(width: 100, height: 100)
.background(Color.gray.opacity(0.7))
.clipShape(Circle())
case .failure:
Image(systemName: "xmark.icloud")
.frame(width: 100, height: 100)
.background(Color.gray.opacity(0.7))
.clipShape(Circle())
@unknown default:
EmptyView()
}
}
}
}
Example of showing an error when downloading an image with AsyncImage

--

--

AsyncLearn

Stay up-to-date in the world of mobile applications with our specialised blog.