首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSONDecoder未能解码嵌套字典

JSONDecoder未能解码嵌套字典
EN

Stack Overflow用户
提问于 2019-03-26 14:34:11
回答 2查看 282关注 0票数 0

我使用JSONDecoder从一个具有嵌套字典的JSON文件中解码。它无法从json数据解码到我的自定义模型。

这就是我在代码中尝试过的。

  1. JSONDecoder看起来如下所示:
代码语言:javascript
复制
let netWorkManager = NetWorkManager(URL: url, httpMethodType: .GET)
        netWorkManager.callAPI { (data, status, error) in
            guard let data = data else {
                onFail(NetWorkError.otherError)
                return
            }

            switch status {
            case 200:
                do{
                    if let responseModel = try JSONDecoder().decode(ResonseModel?.self, from: data) {
                        onSuccess(responseModel)
                    }
                }catch {
                    onFail(NetWorkError.otherError)
                }
            default:
                onFail(NetWorkError.otherError)
            }
        }
  1. 模型如下:
代码语言:javascript
复制
struct ResonseModel: Codable {
    let type : String
    let format: String
    let data: [String: Champion]

    struct Champion: Codable {
        let version: String
        let id: String
        let key: Int
        let name: String
        let title: String
        let blurb: String
    }
}
  1. JSON结构如下所示:
代码语言:javascript
复制
{
    "type": "champion",
    "format": "standAloneComplex",
    "version": "9.3.1",
    "data": {
        "Aatrox": {
            "version": "9.3.1",
            "id": "Aatrox",
            "key": "266",
            "name": "Aatrox",
            "title": "the Darkin Blade",
            "blurb": "Once honored defenders of Shurima against the Void, Aatrox and his brethren would eventually become an even greater threat to Runeterra, and were defeated only by cunning mortal sorcery. But after centuries of imprisonment, Aatrox was the first to find...",
            "info": {
                "attack": 8,
                "defense": 4,
                "magic": 3,
                "difficulty": 4
            },
            "tags": [
                "Fighter",
                "Tank"
            ],
            "partype": "Blood Well",

        },
        "Ahri": {
            "version": "9.3.1",
            "id": "Ahri",
            "key": "103",
            "name": "Ahri",
            "title": "the Nine-Tailed Fox",
            "blurb": "Innately connected to the latent power of Runeterra, Ahri is a vastaya who can reshape magic into orbs of raw energy. She revels in toying with her prey by manipulating their emotions before devouring their life essence. Despite her predatory nature...",
            "info": {
                "attack": 3,
                "defense": 4,
                "magic": 8,
                "difficulty": 5
            },

            "tags": [
                "Mage",
                "Assassin"
            ],
            "partype": "Mana",

        },
        ...

这是JSON的链接,如果您想查看它:US/champion.json

我想将"data“属性解码为字典,其键是冠军的名称,值是冠军。但是jsonDecoder似乎不认识我的模型结构。它最终会抓住错误。

EN

回答 2

Stack Overflow用户

发布于 2019-03-26 15:01:14

JSON参数"key“不是Integer。

将其更改为String,它将工作:

代码语言:javascript
复制
struct ResonseModel: Codable {
    let type : String
    let format: String
    let data: [String: Champion]

    struct Champion: Codable {
        let version: String
        let id: String
        let key: String
        let name: String
        let title: String
        let blurb: String
    }
}
票数 3
EN

Stack Overflow用户

发布于 2019-03-26 19:21:25

您可以切换到手动解码冠军,以清理数据。

代码语言:javascript
复制
struct ResonseModel: Decodable {
    let type : String
    let format: String
    let data: [String: Champion]

    struct Champion: Decodable {
        let version: String
        let id: String
        let key: Int
        let name: String
        let title: String
        let blurb: String

        enum CodingKeys: String, CodingKey {
            case version, id, key, name, title, blurb
        }

        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.version = try container.decode(String.self, forKey: .version)
            self.id = try container.decode(String.self, forKey: .id)
            guard let key = Int(try container.decode(String.self, forKey: .key)) else {
                throw DecodingError.valueNotFound(Int.self,
                                                  .init(codingPath: decoder.codingPath,
                                                        debugDescription: "Bad value for id"))
            }
            self.key = key
            self.name = try container.decode(String.self, forKey: .name)
            self.title = try container.decode(String.self, forKey: .title)
            self.blurb = try container.decode(String.self, forKey: .blurb)
        }
    }
}

这基本上是编译器为您编写的代码;它只是将字符串转换为int,因为这正是您真正想要的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55359730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档