Skip to content

NukeUI - Support for multiple image requests #852

@LePips

Description

@LePips

In my app, I commonly have occurrences where multiple images can be valid inside of a view. Sadly, I am unable to determine which of these images exist prior to requesting them (personal media servers). But, I do have a hierarchy to fetch them in an ordered array. As the first image failed to load, it should request the second, and so on.

This is very much possible in current NukeUI by keeping an array and removing the first until success or failure.

FallbackImageView
struct FallbackImageView: View {
    
    @State
    var sources: [URL]
    
    var body: some View {
        if let currentSource = sources.first {
            LazyImage(url: currentSource) { state in
                if let image = state.image {
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                } else if state.error != nil {
                    Image(systemName: "exclamationmark.triangle")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .foregroundStyle(.red)
                        .onAppear {
                            // Simulate an error after a delay
                            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                                sources.removeFirst()
                            }
                        }
                } else {
                    ProgressView()
                }
            }
            .frame(width: 300, height: 200)
            .clipShape(RoundedRectangle(cornerRadius: 20))
        } else {
            Text("No image available")
        }
    }
}

It would be bit more optimal if NukeUI's LazyImage and internal FetchImage view model could implement this array-fallback functionality as a first-class feature. This could potentially decrease SwiftUI redraws in some cases.

I anticipate this would require a change in architecture of how the current FetchImage state is given to the LazyImage, as we would still only want to run the content closure on progress, error, and/or success. However, in the error instance, we would only get the error from the last image in this case. For a fuller API, it would be desirable for users to catch all of the image errors. We can also assume the images would use the same pipeline.

I could see the desire to get the state change for all of the image requests (like the sample above would), however I argue this is a small use case. Even in my own use case that could be desirable, but I consider it largely out of design consideration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions