Search code examples
apiswiftuiviewmodel

how to fetch data from API and set to the Image


This is my Model And I want to fetch data of publisherBanner and set to the View But I can not set the image in view

    import Foundation


public struct Banner: Decodable {
    public let publisherBanners: [PublisherBanner]

    public init(publisherBanners: [PublisherBanner]) {
        self.publisherBanners = publisherBanners
    }
}

    
    public struct PublisherBanner: Decodable, Hashable {
        public var id = UUID()
    //    public let bannerFor: String
    //    public let imageName: String
        public let url: String
    
        public init(url: String) {
            
    
            self.url = url
        }
    }

  

 

This is my ViewModel

class BannerVM: ObservableObject {
    @Published var datas = [PublisherBanner]()
    let url = "apiUrlExample"
    
    init() {
        getData(url: url)
    }
    
    
    func getData(url: String) {
        guard let url = URL(string: "\(url)") else { return }
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            if let data = data {
                do {
                    let results = try JSONDecoder().decode(Banner.self, from: data)
                    DispatchQueue.main.async {
                        self.datas = results.publisherBanners
                      
                      
                    }
                }
                catch {
                    print(error)
                }
            }
        }.resume()
    }
}

And this is My View where I want to set Image

struct BannerView: View {
@StateObject var bannerObject = BannerVM()
var body: some View{
    ScrollView(.horizontal,showsIndicators: false){
        HStack(spacing:15) {
            ForEach(bannerObject.datas, id: \.id){ item in
                
                AsyncImage(url: URL(string: "\(item.url)")) { image in
                    image
                        .resizable().padding(4)
                        .frame(width: 150, height: 215)
                } placeholder: {
                    Image("logo_gray").resizable().padding(1)
                        .frame(width: 150, height: 215)
                }
                  
                   
            }
        }
   


    }
    .padding(8)
    
}

}

please help me for fetch the Image of My API

I am trying to fetch but i failed many times and please help me. And thank you in advance.


Solution

  • Please read the error message you get

    typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "publisherBanners", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "id", intValue: nil)], debugDescription: "Expected to decode String but found a number instead.", underlyingError: nil))

    It says that the value for key id in PublisherBanner is an Int, you have to declare

    public struct PublisherBanner: Decodable, Hashable, Identifiable  {
        public let id: Int
        public let url: URL
    }
    

    By the way you can decode the url directly to URL and the init method is for free.

    And as PublisherBanner already conforms to Identifiable the code to load the image can be shortened to

    ForEach(bannerObject.datas) { item in
        AsyncImage(url: item.url) { image in
    

    Another by the way is that String Interpolation in URL(string: "\(url)") is redundant because url is already a String. This is sufficient: URL(string: url)