skip to Main Content

I am fetching images from Firebase storage, if there is no image on firebase, I want to show thumbnail,

Thats where I get the error

if let error = error {
          Swift.print(error)
      }

Here is my thumbnail

Image("shoePlaceHolder")
.resizable()
.aspectRatio(contentMode: .fit)

Here is the complete code

func getFullImageURL() {
        let storage = Storage.storage()
        let storagePath = "gs://on-switch.appspot.com/main/(season)/"
        let storageRef = storage.reference(forURL: storagePath)        
        let formattedImageURL = imageURL.absoluteString.replacingOccurrences(of: "file:///", with: "")
        let ref = storageRef.child(formattedImageURL)
        ref.downloadURL { url, error in
            DispatchQueue.main.async {
                if let error = error {
                    Swift.print(error)
                } else if let url = url {
                    fullImageURL = url
                } else {
                    Swift.print("No url and no error")
                }
            }
        }
    }
    
    @ViewBuilder
    var content: some View {
        VStack {
            VStack {
                headerView()
                HStack {
                    AsyncImage(url: $fullImageURL.wrappedValue) { image in
                        image
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                    } placeholder: {
                        Image("shoePlaceHolder")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                    }.frame(width: 260, height: 180)
                        .onAppear(perform: getFullImageURL)
                    VStack(alignment: .leading) {
                        titleView()
                        subtitleView()
                    }
                    Spacer()
                }
            }
            .padding()
            OnDivider()
                .padding(.horizontal)
            SectionView(leadingView: {
                Text("(variants.count) variants")
                    .secondaryText()
            }, trailingView: {
                Image(systemName: "rectangle.expand.vertical")
                    .foregroundColor(Color(.secondaryLabel))
            }).padding()
        }
    

4

Answers


  1. Since no image was shown as an error, you just need to focus on the error. Something like:

    if error.localizedDescription == NoImageErrorString { // NoImageErrorString is something you can find in Firebase code
        // show thumbnail here
    } else {
        // your original code
    }
    
    Login or Signup to reply.
  2. This works for me

    struct ContentView: View {
        @State private var url: URL?
        
        func getFullImageURL() {
            self.url = URL(string: "")
        }
        
        var body: some View {
            VStack {
                AsyncImage(url: url) { image in
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                } placeholder: {
                    Image(systemName: "star")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                }
                .frame(width: 260, height: 180)
                .onAppear(perform: getFullImageURL)
            }
            .padding()
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
       }
    }
    

    If you want to use a custom image, make sure shoePlaceHolder is added to the project Assets.

    Image("shoePlaceHolder")
    

    .
    enter image description here

    enter image description here

    Login or Signup to reply.
  3. You can use a struct instead of a @State, @Published or whatever you’re using to store fullImageURL.

    Something like:

    struct ImageWithErrorPlaceholder {
        var fullImageURL: URL?
        var showErrorPlaceholder: Bool = false
    }
    

    So you can simply inform the URL and the error as needed:

    ref.downloadURL { url, error in
        DispatchQueue.main.async {
            if let error = error {
                imageWithErrorPlaceholder.showErrorPlaceholder = true
                Swift.print(error)
            } else if let url = url {
                imageWithErrorPlaceholder.fullImageURL = url
            } else {
                Swift.print("No url and no error")
            }
        }
    }
    

    That way you can display a different placeholder in case of error or no placeholder at all, depending or your needs:

    AsyncImage(url: imageWithErrorPlaceholder.fullImageURL) { image in
        image
            .resizable()
            .aspectRatio(contentMode: .fit)
    } placeholder: {
        if imageWithErrorPlaceholder.showErrorPlaceholder {
            Image("shoePlaceHolder")
                .resizable()
                .aspectRatio(contentMode: .fit)
        }
    }
    
    Login or Signup to reply.
  4. You have to use this line to invoke the listener for fullImageURL

     fullImageURL = nil
    

    and the complete code will look like this:

    func getFullImageURL() {
            let storage = Storage.storage()
            let storagePath = "gs://on-switch.appspot.com/main/(season)/"
            let storageRef = storage.reference(forURL: storagePath)        
            let formattedImageURL = imageURL.absoluteString.replacingOccurrences(of: "file:///", with: "")
            let ref = storageRef.child(formattedImageURL)
            ref.downloadURL { url, error in
                DispatchQueue.main.async {
                    if let error = error {
                        Swift.print(error)
                        fullImageURL = nil
                    } else if let url = url {
                        fullImageURL = url
                    } else {
                        Swift.print("No url and no error")
                        fullImageURL = nil
                    }
                }
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search