TechnologiesSwiftUI

AsyncImage struct

iOSmacOStvOSwatchOSvisionOSiOS 15.0+✓ renders

A view that asynchronously loads and displays an image.

How it works

AsyncImage is a view that loads and displays an image from a remote URL, performing the download asynchronously so it never blocks your interface. Because SwiftUI views are values that must produce content immediately, you can't simply hand Image a network address and wait; AsyncImage solves this by showing stand-in content while the request is in flight and swapping in the decoded image once it arrives. Reach for it whenever an image's bytes live on the network rather than in your asset catalog or bundle.

  1. Point AsyncImage at a remote URL

    Every AsyncImage is created from a URL?. SwiftUI starts the download as soon as the view appears and manages the request's lifecycle for you, with no completion handlers to write. In the example the source is URL(string: "https://picsum.photos/200"), which yields the optional URL the view fetches.

  2. Shape the loaded image with the content closure

    The trailing content closure receives the successfully loaded Image so you can style it before it's shown. This is where you make the image fit its box: image.resizable() lets it scale, and .scaledToFit() preserves its aspect ratio within the available space.

  3. Fill the gap with a placeholder

    The placeholder closure supplies whatever should appear while the download is still running or if it never resolves. It keeps your layout from collapsing and signals progress to the reader; here it returns a ProgressView() spinner that occupies the frame until the real image is ready.

  4. Constrain and decorate the result

    AsyncImage is an ordinary View, so standard modifiers applied to it affect both the placeholder and the final image, keeping the slot stable across the swap. The example pins the size with .frame(width: 120, height: 120), rounds the corners using .clipShape(RoundedRectangle(cornerRadius: 12)), and adds breathing room with .padding().

Try it — Change the url argument to a deliberately broken address like URL(string: "https://picsum.photos/does-not-exist") and watch the placeholder ProgressView remain in place when the load never succeeds.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

AsyncImage.swift
struct AsyncImageDemo: View {
    var body: some View {
        AsyncImage(url: URL(string: "https://picsum.photos/200")) { image in
            image
                .resizable()
                .scaledToFit()
        } placeholder: {
            ProgressView()
        }
        .frame(width: 120, height: 120)
        .clipShape(RoundedRectangle(cornerRadius: 12))
        .padding()
    }
}
Live preview
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →