Swift Codable解码:如何指定key解析API返回的dogs数组
解码JSON中指定键对应的Animal数组解决方案
你现在遇到的问题是,JSON的最外层是一个包含dogs和cats键的对象,而非直接的Animal数组,所以直接用JSONDecoder().decode([Animal].self, from: data)会失败——解码器找不到匹配的数组结构。这里有两种实用的解决方法:
方法一:创建顶层响应模型(推荐)
这是最贴合Swift Codable设计理念的方式,类型安全且易维护。我们只需要定义一个包含dogs属性的顶层结构体,先解码这个结构体,再取出里面的dogs数组:
import Foundation // 你已定义的Animal模型 public struct Animal: Codable { let name: String? } // 新增顶层响应模型,匹配JSON外层结构 struct AnimalsResponse: Codable { let dogs: [Animal] // 如果后续需要处理cats,也可以添加`let cats: [Animal]` } // 修改后的解码代码 do { let decodedResponse = try JSONDecoder().decode(AnimalsResponse.self, from: response.data!) let dogs = decodedResponse.dogs // 这里就得到了dogs对应的Animal数组,可直接使用 } catch { print("解码错误:\(error)") }
这种方法的优势是结构清晰,后续如果JSON结构发生变化(比如新增字段),只需修改顶层模型即可,全程有编译器的类型检查保驾护航,减少出错概率。
方法二:通过JSONSerialization先提取指定键的数据
如果你不想新增额外模型,可以先用JSONSerialization把Data转成字典,提取出dogs对应的部分,再转回Data后解码:
do { // 先将Data转为JSON对象 guard let jsonObject = try JSONSerialization.jsonObject(with: response.data!) as? [String: Any], // 取出dogs对应的数组 let dogsArray = jsonObject["dogs"] as? [[String: Any]] else { print("无法提取dogs数据") return } // 将dogs数组重新转为Data let dogsData = try JSONSerialization.data(withJSONObject: dogsArray) // 解码成Animal数组 let dogs = try JSONDecoder().decode([Animal].self, from: dogsData) // 使用dogs数组 } catch { print("处理错误:\(error)") }
这种方法适合临时场景,但缺点是失去了Codable的类型安全优势,需要手动处理类型转换,相对容易出错。
内容的提问来源于stack exchange,提问作者etayluz
相关产品推荐
相关产品推荐

