How to Use AsyncImage in SwiftUI
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
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())
}
}
}
- Here we have an
Image
view, so we can use all theImage
modifiers, such asresizable()
, and adjust the image size by changing theframe
.
- 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.
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 ourProgressView
.
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()
}
}
}
}