In this swiftUI tutorial we are going to cover about asyncronous programing to load image from url. In order to render remote images from URLs, SwiftUI provided a struct called as AsyncImage.
Here is a simple way to render image from URLs using AsyncImage
AsyncImage(url: imageURL) |
Where imageURL is of URL type. I will be taking sample remote image URL in this example,
let imageLink = "https://images.pexels.com/photos/2893685/pexels-photo-2893685.jpeg" AsyncImage(url: URL(string: imageLink)) |
By default, AsyncImage
will render the downloaded image according to its pixel size, without cropping or resizing it in any way. That might be what we want in certain situations, but in some contexts that could result in our image being drawn way too large — perhaps even outside the bounds of the screen.
An initial idea on how to address that, for example by constraining our image to a certain max width and height, might be to use the frame
modifier that’s very commonly used in SwiftUI in general:
AsyncImage(url: URL(string: imageLink)) .frame(width: 300, height: 600, alignment: .center) |
However, the above only changes the frame of the container used to render our image, it doesn’t actually resize our image itself (which can still end up being drawn out of bounds). To actually change the size of our image, we instead have to use another AsyncImage
initializer which gives us more precise control over how both the image, and its placeholder, should be rendered:
AsyncImage(url: URL(string: imageLink)) { image in image.resizable() .frame(width: 300, height: 600, alignment: .center) .scaledToFit() .cornerRadius(10) } placeholder: { ProgressView() } |
Here, we are resizing an image downloaded from the URL and the placeholder used to show till the image gets rendered but here there is another issue. ProgressView shows up even if the image was failed to download. End user may think that the image is still loading by looking at the progress view. To resolve this kind of UX issues, we can use another initializer of AsyncImage where we will have control of failure case.
AsyncImage(url: URL(string: imageLink)) { phase in switch phase { case .empty: ProgressView() case .failure(_): Color.purple case .success(let image): image.resizable() .frame(width: 300, height: 600, alignment: .center) @unknown default: Color.red } } |
Here the phase will indicate the state of image download.
Like above while loading the image we can add animation effect to the widget, here is the animation instance is provided to the transaction
argument this time
AsyncImage(url: URL(string: imageLink), transaction: Transaction(animation: .easeInOut(duration: 2.5)) ) { phase in switch phase { case .empty: ProgressView() case .failure(_): Color.purple case .success(let image): image.resizable() .frame(width: 300, height: 600, alignment: .center) @unknown default: Color.red } } |
AsyncImage
states that it will always use the app’s default URLSession.shared
instance to perform each network call, and besides the caching that comes built into URLSession
itself, there doesn’t seem to be a way to add any additional caching layers on top of that.
Conclusion:
In this article, you learnt how to render image from remote URL and the ways to use in different cases.
Article Contributed By :
|
|
|
|
935 Views |