apiswiftuiswiftui-asyncimage

async image in SwiftUI


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?


Solution

  • 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.