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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:50:27