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 = "https://www.alibrary.in/api/web-home"
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
This is my Api
[https://www.alibrary.in/api/web-home][1]
I am trying to fetch but i failed many times and please help me. And thank you in advance.
CodePudding user response:
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)