首页 > 解决方案 > 将嵌套的 JSON REST Api 响应解码为结构数组

问题描述

我正在尝试将 https://swapi.dev/api/people/的响应解析为 aList但由于嵌套响应结构而不是平坦响应,我似乎无法使其工作。

这是我的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()
    }

}

我有一个CharactersResponse结构:

struct CharactersResponse {
    let count: Int
    let next: String
    let previous: NSNull
    let results: [Character]
}

和一个Character结构:

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
}

我得到的错误是Value of type 'Data' has no member 'results',但我不确定如何修复它以便将其解析为结构CharactersResponse results数组。Character

在此处输入图像描述

标签: swiftrestswiftui

解决方案


您正在混淆原始数据和反序列化的结构

代替

if let charactersResponse = try? JSONDecoder().decode([Character].self, from: data.results) { ...

if let charactersResponse = try? JSONDecoder().decode(CharactersResponse.self, from: data) { ...

Decodable并采用CharactersResponse

struct CharactersResponse : Decodable { ...

您也可以替换NSNull为预期类型的​​可选


永远不要try?JSONDecoder上下文中。catch一个潜在的错误并打印出来。

do {   
    let charactersResponse = try JSONDecoder().decode(CharactersResponse.self, from: data) { ...

} catch { print(error) }

推荐阅读