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

Swift使用Decodable自定义解析深层嵌套JSON到指定Beer结构体

实现方案

你不需要为外层嵌套层级单独定义结构体,只需要通过自定义 [Beer] 数组类型的解码逻辑,逐层穿透JSON的嵌套层级拿到目标数据即可,完整实现如下:

完整代码

import Foundation

// 仅需定义Beer结构体即可
struct Beer: Decodable {
    let id: Int
    let name: String
    let style: String
}

// 扩展Array类型,当元素为Beer时自定义解码逻辑
extension Array: Decodable where Element == Beer {
    public init(from decoder: Decoder) throws {
        // 定义局部CodingKey,仅用于当前解码逻辑,不会对外暴露
        struct CodingKeys: CodingKey {
            var stringValue: String
            init?(stringValue: String) {
                self.stringValue = stringValue
            }
            var intValue: Int?
            init?(intValue: Int) { nil }
            
            static let response = CodingKeys(stringValue: "response")!
            static let list = CodingKeys(stringValue: "list")!
            static let beers = CodingKeys(stringValue: "beers")!
            static let beer = CodingKeys(stringValue: "beer")!
        }
        
        // 第一层:取根节点下的response容器
        let rootContainer = try decoder.container(keyedBy: CodingKeys.self)
        let responseContainer = try rootContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .response)
        
        // 第二层:取response下的list容器
        let listContainer = try responseContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .list)
        
        // 第三层:取list下的beers数组容器
        var beersArrayContainer = try listContainer.nestedUnkeyedContainer(forKey: .beers)
        
        var result = [Beer]()
        // 遍历数组容器解码每个Beer对象
        while !beersArrayContainer.isAtEnd {
            let itemContainer = try beersArrayContainer.nestedContainer(keyedBy: CodingKeys.self)
            let beer = try itemContainer.decode(Beer.self, forKey: .beer)
            result.append(beer)
        }
        
        self = result
    }
}

使用方式

直接对整个JSON数据调用解码方法即可得到Beer数组:

let jsonData: Data = ... // 你的JSON数据
let decoder = JSONDecoder()
do {
    let beers = try decoder.decode([Beer].self, from: jsonData)
    print(beers) // 得到解析完成的Beer数组
} catch {
    print("解码失败: \(error)")
}

逻辑说明

  • 局部定义的CodingKey仅服务于本次解码逻辑,不需要对外暴露,也不需要单独定义全局结构体
  • 多层嵌套的字典结构通过nestedContainer(keyedBy:forKey:)逐层向下获取容器
  • 数组类型的嵌套结构通过nestedUnkeyedContainer(forKey:)获取无键容器,遍历逐个解码元素
  • Beer本身的属性和JSON中beer对象的字段完全匹配,不需要自定义解码逻辑,使用系统自动合成的实现即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 03:27:03