0
0
iOS Swiftmobile~20 mins

Image loading from URL in iOS Swift - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Image Loader
This screen loads and displays an image from a web URL. It shows a placeholder while loading and an error message if loading fails.
Target UI
-------------------------
|       Image Loader     |
|-----------------------|
|  [Placeholder Image]   |
|                       |
|  Loading image...      |
|                       |
|-----------------------|
|       Reload Button    |
-------------------------
Display an image loaded from a given URL.
Show a placeholder image while the image is loading.
Show a text message if the image fails to load.
Add a button labeled 'Reload' to retry loading the image.
Starter Code
iOS Swift
import SwiftUI

struct ImageLoaderView: View {
    // TODO: Add state variables here

    var body: some View {
        VStack {
            // TODO: Add image view here

            // TODO: Add status text here

            Button("Reload") {
                // TODO: Add reload action here
            }
            .padding()
        }
        .padding()
        .onAppear {
            // TODO: Load image when view appears
        }
    }
}

struct ImageLoaderView_Previews: PreviewProvider {
    static var previews: some View {
        ImageLoaderView()
    }
}
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
iOS Swift
import SwiftUI

struct ImageLoaderView: View {
    @State private var image: UIImage? = nil
    @State private var isLoading = false
    @State private var errorMessage: String? = nil

    let imageUrl = URL(string: "https://picsum.photos/300")!

    var body: some View {
        VStack(spacing: 20) {
            if let uiImage = image {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFit()
                    .frame(maxWidth: 300, maxHeight: 300)
                    .cornerRadius(8)
                    .accessibilityLabel(Text("Loaded image from internet"))
            } else if isLoading {
                Image(systemName: "photo")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 100, height: 100)
                    .foregroundColor(.gray)
                    .accessibilityHidden(true)
                Text("Loading image...")
                    .accessibilityLabel(Text("Loading image"))
            } else if let error = errorMessage {
                Image(systemName: "exclamationmark.triangle")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 80, height: 80)
                    .foregroundColor(.red)
                    .accessibilityHidden(true)
                Text(error)
                    .foregroundColor(.red)
                    .accessibilityLabel(Text("Error loading image"))
            } else {
                Image(systemName: "photo")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 100, height: 100)
                    .foregroundColor(.gray)
                    .accessibilityHidden(true)
                Text("No image loaded")
                    .accessibilityLabel(Text("No image loaded"))
            }

            Button("Reload") {
                loadImage()
            }
            .padding()
            .accessibilityLabel(Text("Reload image button"))
        }
        .padding()
        .onAppear {
            loadImage()
        }
    }

    func loadImage() {
        isLoading = true
        errorMessage = nil
        image = nil

        let task = URLSession.shared.dataTask(with: imageUrl) { data, response, error in
            DispatchQueue.main.async {
                isLoading = false
                if let error = error {
                    errorMessage = "Failed to load image: \(error.localizedDescription)"
                    return
                }
                guard let data = data, let uiImage = UIImage(data: data) else {
                    errorMessage = "Invalid image data"
                    return
                }
                image = uiImage
            }
        }
        task.resume()
    }
}

struct ImageLoaderView_Previews: PreviewProvider {
    static var previews: some View {
        ImageLoaderView()
    }
}

This SwiftUI view uses @State variables to track the image, loading state, and error message. When the view appears, it calls loadImage() which starts a URLSession data task to fetch the image data from the URL.

While loading, it shows a placeholder system image and a loading text. If loading fails, it shows an error icon and message. When the image loads successfully, it displays the image with a nice corner radius.

The Reload button calls loadImage() again to retry loading the image. Accessibility labels are added for screen readers. The UI is simple and responsive, showing clear states for loading, success, and error.

Final Result
Completed Screen
-------------------------
|       Image Loader     |
|-----------------------|
|   [Loaded Image]       |
|                       |
|                       |
|                       |
|-----------------------|
|       Reload Button    |
-------------------------
When the screen appears, the app starts loading the image from the URL.
While loading, a placeholder icon and 'Loading image...' text show.
If loading succeeds, the image appears in the center.
If loading fails, an error icon and message appear instead.
Tapping the 'Reload' button retries loading the image.
Stretch Goal
Add a progress indicator (spinner) while the image is loading.
💡 Hint
Use SwiftUI's ProgressView inside the loading state to show a spinner.