Load remote images using AsyncImage in SwiftUI

Starting from SwiftUI 3.0, loading remote images in an application doesn't require a third-party package anymore: it's built-in with AsyncImage! In this section, we'll take a look at this new view and learn how easy it is to implement it.

Disclaimer

AsyncImage is only supported in applications running on iOS 15.0 and higher. You'll need Xcode 13 and need to set your Xcode project's iOS target version to iOS 15.0 or higher, or wrap the code presented in this section in an if #available(iOS 15.0, *).

Create the AsyncImage

AsyncImage requires one parameter, which is the URL. Pass in the URL of the image you wish to display to AsyncImage. Remember to click on Play in the Preview in order to load the image into your application.

AsyncImage(url: URL(string: "https://images.ctfassets.net/ooa29xqb8tix/J6KiaOqQyBtSa84hx6fuI/2cd1d475743a2a42c8643b2a69e88547/Advanced_React_Hooks_800x600_cover.png?w=400&q=50")!)

..

Add modifiers

Inside of a closure, we can get the image returned by AsyncImage and add some modifiers to it.

AsyncImage(url: URL(string: "https://images.ctfassets.net/ooa29xqb8tix/J6KiaOqQyBtSa84hx6fuI/2cd1d475743a2a42c8643b2a69e88547/Advanced_React_Hooks_800x600_cover.png?w=400&q=50")!) { image in
    image
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(maxWidth: 220, alignment: .center)
}

..

However, you might into a few errors if you add a few modifiers to your AsyncImage.

Add placeholder

To solve this issue, we'll need to provide a placeholder to the AsyncImage as well, because accessing the image within the closure requires a placeholder as well.

For my placeholder, I'll have a loading indicator while the image is being fetched from the server, but you can add anything you want - a colored rectangle, a rotating circle, or any other loading indicator that you prefer.

..

AsyncImage(url: URL(string: "https://images.ctfassets.net/ooa29xqb8tix/J6KiaOqQyBtSa84hx6fuI/2cd1d475743a2a42c8643b2a69e88547/Advanced_React_Hooks_800x600_cover.png?w=400&q=50")!) { image in
    image
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(maxWidth: 220, alignment: .center)
} placeholder: {
    ProgressView()
}

..


Comments