Reputation: 11042
I am trying to parse the response of https://swapi.dev/api/people/ in to a List
but I can't seem to get it work due to the nested response structure instead of a flat response.
This is my ContentView
:
struct ContentView: View {
private let charactersURL = URL(string: "https://swapi.dev/api/people/")!
@State private var characters: [Character] = []
var body: some View {
NavigationView {
VStack {
List {
ForEach(characters, id: \.self) { character in
NavigationLink(destination: CharacterView(character: character)) {
Text(character.name)
}
}
}
.onAppear(perform: loadCharacter)
}
.navigationBarTitle("Swapi Api Client")
}
}
private func loadCharacter() {
let request = URLRequest(url: charactersURL)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let charactersResponse = try? JSONDecoder().decode([Character].self, from: data.results) {
withAnimation {
self.characters = charactersResponse.results
}
}
}
}.resume()
}
}
I have a CharactersResponse
struct:
struct CharactersResponse {
let count: Int
let next: String
let previous: NSNull
let results: [Character]
}
and a Character
struct:
struct Character: Decodable, Hashable {
let name: String
let height: Int
let mass: String
let hairColor: String
let skinColor: String
let eyeColor: String
let birthYear: String
let gender: String
let homeworld: String
let films: [String]
let species: [String]
let vehicles : [String]
let starships: [String]
let created: String
let edited: String
let url: String
}
The error I get is Value of type 'Data' has no member 'results'
but I'm not sure how to fix it so that the CharactersResponse
results
are parsed in to an array of Character
structs.
Upvotes: 1
Views: 258
Reputation: 285039
You are mixing up the raw data and the deserialized structs
Replace
if let charactersResponse = try? JSONDecoder().decode([Character].self, from: data.results) { ...
with
if let charactersResponse = try? JSONDecoder().decode(CharactersResponse.self, from: data) { ...
And adopt Decodable
in CharactersResponse
struct CharactersResponse : Decodable { ...
You might also replace NSNull
with an optional of the expected type
Never try?
in a JSONDecoder
context. catch
a potential error and print it.
do {
let charactersResponse = try JSONDecoder().decode(CharactersResponse.self, from: data) { ...
} catch { print(error) }
Upvotes: 2