You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中调用Pokemon API获取数据时JSON解码失败问题排查

解决JSON解码失败的问题

你的问题核心是结构体属性名和JSON中的键不匹配,导致JSONDecoder无法正确映射数据,从而输出"Error Parsing JSON"。下面是具体的分析和解决步骤:

1. 定位问题根源

看一下返回的JSON结构,包含的数组键是results,但你的PokemonList结构体里定义的属性是pokemon——JSONDecoder默认会用结构体的属性名去匹配JSON的键,找不到对应键时就会解码失败。

2. 修正结构体定义

有两种方式解决这个键不匹配的问题:

方式一:直接修改属性名匹配JSON键

最简单的方法是把PokemonList的属性名改成results,和JSON中的键完全一致:

struct PokemonList: Decodable {
    let results: [Pokemon] // 改为results,对应JSON中的键
}

// 同时简化Pokemon结构体——因为属性名和JSON键完全匹配,不需要自定义init,自动合成Decodable即可
struct Pokemon: Decodable {
    let name: String
    let url: String
}

然后在fetchPokemon函数里,把获取数组的代码改成:

let pokemon = result.results
self.Pokemon = pokemon

方式二:用CodingKey映射保留原属性名

如果你想继续使用pokemon作为属性名,可以通过自定义CodingKeys来映射JSON的results键:

struct PokemonList: Decodable {
    var pokemon: [Pokemon]
    
    // 自定义CodingKey,将JSON的results映射到结构体的pokemon属性
    enum CodingKeys: String, CodingKey {
        case pokemon = "results"
    }
}

这种情况下,fetchPokemon里的代码不需要修改,依然可以用result.pokemon获取数组。

3. 调试技巧:捕获具体错误

建议把try?改成do-catch块,这样能打印出具体的解码错误信息,方便快速定位问题:

DispatchQueue.main.async {
    do {
        let result = try JSONDecoder().decode(PokemonList.self, from: data!)
        self.Pokemon = result.results // 或者result.pokemon,根据你的结构体修改
        print(self.Pokemon)
    } catch {
        print("Error Parsing JSON: \(error)")
    }
}

比如原来的错误会打印出keyNotFound(CodingKeys(stringValue: "pokemon", intValue: nil), ...),一眼就能看出是键不匹配的问题。

内容的提问来源于stack exchange,提问作者ajnauleau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:02:34