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
相关产品推荐
相关产品推荐

