简体   繁体   中英

SWIFTUI Displaying JSON Data in ContentView

I have been having trouble displaying my JSON into my content view. I can decode the data and save it into a dictionary as I have printed and seen. However when its time to display it in ContentView with a ForEach. I'm getting this error Cannot convert value of type '[String: String]' to expected argument type 'Binding' Below is my code for my ContentView, Struct and ApiCall. I have read other solutions on stackoverflow and tried them all but they do not work.

struct ContentView: View { 

    @StateObject var api = APICALL()
    
    var body: some View {
        let country = api.storedData.countries
        
        VStack(alignment: .leading) {
            ForEach(country.id, id: \.self) { country in
                HStack(alignment: .top) {
                    Text("\(country.countries)")
                }
                
            }
            .onAppear {
                api.loadData()
            }
        }
    }
}

My ApiCall class which loads the data, as well as the struct.

// MARK: - Country
struct Country: Codable, Identifiable {
    let id = UUID()
    var countries: [String: String]

    enum CodingKeys: String, CodingKey {
        case countries = "countries"
    }
}

class APICALL: ObservableObject {
    
    @Published var storedData = Country(countries: [:])
    
    func loadData() {
        let apikey = ""
        
        guard let url = URL(string:"https://countries-cities.p.rapidapi.com/location/country/list?rapidapi-key=\(apikey)") else {
            print("Your Api end point is Invalid")
            return
        }
        let request = URLRequest(url: url)
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                if let response = try? JSONDecoder().decode(Country.self, from: data) {
                    DispatchQueue.main.async {
                        self.storedData.countries = response.countries
                        print(self.storedData.countries)
                    }
                    return
                }
            }
        }
        .resume()
    }
}

Any Point in the right direction would be absolutely helpful.

you could try this approach to display your countries data:

struct ContentView: View {
    @StateObject var api = APICALL()
    
    var body: some View {
        VStack(alignment: .leading) {
            // -- here --
            ForEach(Array(api.storedData.countries.enumerated()), id: \.0) { index, country in 
                HStack(alignment: .top) {
                    Text("\(country.key)   \(country.value)")
                }
            }
            .onAppear {
                api.loadData()
            }
        }
    }
}

you can also use this, if you prefer:

    ForEach(api.storedData.countries.sorted(by: >), id: \.key) { key, value in
        HStack(alignment: .top) {
            Text("\(key)   \(value)")
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM