I couldn't find a way to use my Structure in a ContentView. Structure fills correctly, but that's it. How can I replace example array in a View:
let countries = ["Germany", "Egypt", "Italy"] // example
with a real array of Countries from:
let countries: CountriesWikiData = await decodeWikiData(from: countriesQuery)
struct CountriesWikiData: Decodable {
let head: CountriesHead
let results: CountriesResults
}
struct CountriesHead: Decodable {
let vars: [String]
}
struct CountriesResults: Decodable {
let bindings: [CountriesBindings]
}
struct CountriesBindings: Decodable {
let country: [String: String]
let countryLabel: [String: String]
}
func decodeWikiData<T: Decodable>(from url: String) async -> T {
let url = URL(string: url)!
let request = URLRequest(url: url)
do {
let (data, _) = try await URLSession.shared.data(for: request)
guard
let jsonObj = try? JSONSerialization.jsonObject(with: data, options: []),
let jsonData = try? JSONSerialization.data(withJSONObject: jsonObj, options: .prettyPrinted)
else {
fatalError("Cannot convert data to JSON.")
}
guard let strc = try? JSONDecoder().decode(T.self, from: jsonData)
else {
fatalError("Cannot make a structure.")
}
return strc // Wheeeee!!
} catch {
fatalError("Cannot get data from URL.")
}
}
struct ContentView: View {
/*
SELECT DISTINCT ?country ?countryLabel
WHERE
{
?country wdt:P31 wd:Q3624078.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
*/
let countriesQuery = "https://query.wikidata.org/sparql?query=SELECT%20DISTINCT%20%3Fcountry%20%3FcountryLabel%0AWHERE%0A%7B%0A%20%20%3Fcountry%20wdt%3AP31%20wd%3AQ3624078.%0A%20%20SERVICE%20wikibase%3Alabel%20%7B%20bd%3AserviceParam%20wikibase%3Alanguage%20%22en%22%20%7D%0A%7D&format=json"
let countries = ["Germany", "Egypt", "Italy"] // example
@State var selectedCountry = ""
//let countries: CountriesWikiData = await decodeWikiData(from: countriesQuery)
var body: some View {
VStack {
Picker("", selection: $selectedCountry) {
ForEach(countries, id: \.self) {
Text($0)
}
}
}
}
}
You could try this approach to display the results of the API call using the model structs as shown in the example code.
The approach uses a modified
CountriesBindingswithCountryandCountryLabelstructs. An updatedfunc decodeWikiData(...)in a.task {...}view modifier and aPickerwith the important.tag(country.value)