Marvel API Swift4 JSON解码

时间:2018-11-22 16:55:57

标签: json swift api nested decode

我正在基于Apple撰写的《用Swift开发应用程序》一书制作一个基本的IOS应用程序。我的应用程序使用Marvel API。我正在尝试获得英雄的名字和描述。
与API的连接完全可以正常工作,并且已经过多次测试。问题与此无关。

我的问题是JSON结果嵌套了3次,我不知道如何在Swift 4中做到这一点。

这里是1位英雄的JSON结果的示例。所有英雄都可以在“结果”中找到

The JSON structure can be found here

我的代码有一个致命错误:

  

Swift.DecodingError.keyNotFound(CodingKeys(stringValue:“ results”,intValue:nil)

let jsonDecoder = JSONDecoder()
    let task = URLSession.shared.dataTask(with: url) { (data,
        response, error) in
        try! jsonDecoder.decode(CharactersContainer.self, 
from: data!) //error here
        if let data = data,
            let char = try? jsonDecoder.decode(CharactersContainer.self, from: data) {
            print(char.characters)
            print("succes")

        } else {
            print("failed")
        }
    }

现在这是我的模特:

import Foundation

struct Character: Codable {
    var name: String
    var description: String
    //var url: Image


    enum CodingKeys: String, CodingKey {
        case name
        case description
        //case url = "thumbnail"

    }
    init(from decoder: Decoder) throws {
        let valueContainer = try decoder.container(keyedBy: CharactersContainer.CodingKeys.self).nestedContainer(keyedBy: Characters.CodingKeys.self, forKey: .characters).nestedContainer(keyedBy: Character.CodingKeys.self, forKey: .characters)
        if let name = try valueContainer.decodeIfPresent(String.self, forKey: CodingKeys.name) {
            self.name = name
        } else {
            self.name = ""
        }
        if let description = try valueContainer.decodeIfPresent(String.self, forKey: CodingKeys.description) {
            self.description = description
        } else {
            self.description = ""
        }

       // self.url = try valueContainer.decode(URL.self, forKey: CodingKeys.url)

    }
}



struct Characters : Decodable{
    var characters : [Character]
    enum CodingKeys: String, CodingKey {
        case characters = "data"
    }
}

struct CharactersContainer : Decodable {
    var characters : Characters
    //var total: Int
    enum CodingKeys: String, CodingKey {
        case characters = "results"
        //case total
    }
}

我不知道自己做错了什么,因为我看到了一些完全一样的例子。

感谢签到!

1 个答案:

答案 0 :(得分:0)

在JSON中,data包含results键。设置密钥的方式期望results包含一个data密钥。

CharactersContainer.CodingKeys.characters应该是"data"

Characters.CodingKeys.characters应该是"results"


编辑:

Character中还有另一个问题。它试图获取以CharactersContainer.CodingKeys.self为键的包含,但它可能应该是Character.CodingKeys.self