Skip to content
DeveloperMemos

Using AsyncImage in SwiftUI

SwiftUI, iOS Development, Images1 min read

Loading images from a remote URL is a common requirement in modern iOS apps. Before iOS 15, developers often relied on third-party libraries like Kingfisher or SDWebImage, or wrote their own custom image loaders. With the introduction of AsyncImage in iOS 15, SwiftUI provides a built-in way to asynchronously load and display images.

In this article, we'll explore how to use AsyncImage to load images from the web.

Basic Usage

The simplest way to use AsyncImage is by providing a URL. SwiftUI handles the downloading and displaying for you.

1import SwiftUI
2
3struct ContentView: View {
4 let imageURL = URL(string: "https://picsum.photos/200")
5
6 var body: some View {
7 AsyncImage(url: imageURL)
8 }
9}

This will load the image and display it. However, until the image is loaded, the view will be empty (or show a default placeholder depending on the context), and you don't have control over the image's resizing behavior.

Resizing and Placeholders

To resize the loaded image or provide a custom placeholder while it's loading, you can use the initializer that takes a content closure and a placeholder closure.

1AsyncImage(url: imageURL) { image in
2 image
3 .resizable()
4 .aspectRatio(contentMode: .fit)
5} placeholder: {
6 ProgressView()
7}
8.frame(width: 200, height: 200)

In this example:

  • The content closure gives you access to the loaded Image, allowing you to apply modifiers like .resizable().
  • The placeholder closure lets you display a view while the image is loading, such as a ProgressView or a static placeholder image.

Handling Loading States with AsyncImagePhase

For more granular control, you can use the initializer that provides an AsyncImagePhase. This allows you to handle three states: empty (loading), success (image loaded), and failure (error).

1AsyncImage(url: imageURL) { phase in
2 switch phase {
3 case .empty:
4 ProgressView()
5 case .success(let image):
6 image
7 .resizable()
8 .aspectRatio(contentMode: .fit)
9 case .failure:
10 Image(systemName: "photo")
11 .foregroundColor(.gray)
12 @unknown default:
13 EmptyView()
14 }
15}
16.frame(width: 200, height: 200)

This approach is robust because it lets you show a fallback image if the download fails, which is great for user experience.

Caching Note

It is important to note that AsyncImage uses the shared URLSession for networking, but it does not persist images to disk by default. If you need advanced caching capabilities (like disk caching or custom cache policies), you might still want to look into third-party libraries or implement a custom solution. However, for simple use cases, AsyncImage is incredibly convenient.

Conclusion

AsyncImage simplifies the process of loading remote images in SwiftUI, removing the need for external dependencies for basic tasks. Whether you need a quick image load or full control over loading states, AsyncImage has you covered.

Give it a try in your next SwiftUI project!