I am working on an api, in which i retrieve the texts but the image from the api is not showing inside the view. I have given it an async image. The async image shows as a grey part in the view. Please let me know what is missing here. It would be great if someone would help me out with this.
API modal as:
struct priceRange: Codable {
let status: String
let record: Record
}
struct Record: Codable {
let propertytype: [Property]
let placetype: [Place]
let floorplan: [Floor]
let amenity: [Amenity]
let path: String
}
struct Property: Codable {
let type: String
let image: String
let status: String
let id: Int
}
My network code goes here:
class PRViewModel: ObservableObject {
@Published var floors = [Floor]()
@Published var place = [Place]()
@Published var prop = [Property]()
@Published var res = [Amenity]()
@Published private(set) var exp: priceRange?
@Published private(set) var rec: Record?
func loadData(){
guard let url = URL(string: PR_data) else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) {(data, response, error) in
do {
if let todoData = data {
let decodedData = try JSONDecoder().decode(priceRange.self, from: todoData)
DispatchQueue.main.async {
self.res = decodedData.record.amenity
self.prop = decodedData.record.propertytype
self.floors = decodedData.record.floorplan
self.place = decodedData.record.placetype
print(decodedData.status)
//print(decodedData.record.path!)
}
} else {
print("No data")
}
} catch {
print(error)
}
}.resume()
}
}
List code goes here :
struct Price_range: View {
@StateObject var viewModel = PRViewModel()
var body: some View {
List(viewModel.prop, id: \.type) { item in
Text(item.type)
AsyncImage(url: URL(string: PR_URL + (viewModel.rec?.path ?? "") + "/" + item.image))
}
.onAppear {
viewModel.loadData()
}
}
}
Edit:
AsyncImage(url: URL(string: PR_URL + (viewModel.exp?.record.path ?? "") + "/" + item.image))
it still remains the same. I want to bring that “path” variable in the “record” modal to the view?
As allready pointed out in the comments you never assign any value to exp
and res
so they stay nil. You could assign them while you assign your previous properties:
do {
if let todoData = data {
let decodedData = try JSONDecoder().decode(priceRange.self, from: todoData)
DispatchQueue.main.async {
self.exp = decodedData // this
self.rec = decodedData.record // and this
self.res = decodedData.record.amenity
self.prop = decodedData.record.propertytype
self.floors = decodedData.record.floorplan
self.place = decodedData.record.placetype
print(decodedData.status)
//print(decodedData.record.path!)
}
} else {
print("No data")
}
} catch {
print(error)
}
and then do:
AsyncImage(url: URL(string: PR_URL + (viewModel.rec?.path ?? "") + "/" + item.image))
if there is still an issue try to verify your link is valid by using:
let _ = print(PR_URL + (viewModel.rec?.path ?? "") + "/" + item.image)
right before the line with the AsyncImage
.