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

Swift 5下混合类型与键控/无键混合结构JSON解码问题求助

Swift 5 异构JSON解码解决方案

步骤1:定义内层混合类型枚举

用于处理同一数组中同时存在Int和String类型的元素

enum StringOrInt: Codable {
    case int(Int)
    case string(String)
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        // 优先尝试解码Int类型
        if let intVal = try? container.decode(Int.self) {
            self = .int(intVal)
            return
        }
        // 解码Int失败则尝试解码String类型
        if let stringVal = try? container.decode(String.self) {
            self = .string(stringVal)
            return
        }
        // 两种类型都不匹配抛出异常
        throw DecodingError.dataCorruptedError(in: container, debugDescription: "Value is neither Int nor String")
    }
}

步骤2:定义外层异构数组元素枚举

用于处理外层无键数组中同时存在Int、字典、String三种类型的元素

enum OuterElement: Codable {
    case int(Int)
    case dict([String: [StringOrInt]])
    case string(String)
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        // 匹配整数类型
        if let intVal = try? container.decode(Int.self) {
            self = .int(intVal)
            return
        }
        // 匹配键控字典类型,值为混合类型数组
        if let dictVal = try? container.decode([String: [StringOrInt]].self) {
            self = .dict(dictVal)
            return
        }
        // 匹配字符串类型
        if let stringVal = try? container.decode(String.self) {
            self = .string(stringVal)
            return
        }
        throw DecodingError.dataCorruptedError(in: container, debugDescription: "Unsupported outer element type")
    }
}

步骤3:解码调用示例

// 加载JSON数据
let jsonData = """
[
  12,
  {
    "a": [
      "orange",
      10,
      "purple"
    ],
    "b": [
      "red",
      9,
      "blue"
    ],
    "c": [
      "yellow",
      "green"
    ]
  },
  "string one",
  "string two"
]
""".data(using: .utf8)!

// 执行解码
do {
    let decodeResult = try JSONDecoder().decode([OuterElement].self, from: jsonData)
    // 取值示例
    for item in decodeResult {
        switch item {
        case .int(let num):
            print("外层整数:\(num)")
        case .dict(let dict):
            print("外层字典内容:")
            for (key, valueArr) in dict {
                print("键\(key)的数组元素:")
                valueArr.forEach { element in
                    switch element {
                    case .int(let num): print("  整数:\(num)")
                    case .string(let str): print("  字符串:\(str)")
                    }
                }
            }
        case .string(let str):
            print("外层字符串:\(str)")
        }
    }
} catch {
    print("解码错误:\(error.localizedDescription)")
}

核心逻辑说明

  • 所有异构类型统一用带关联值的Codable枚举封装,不需要手动解析整个JSON结构,仅处理类型匹配分支即可
  • 解码时按优先级尝试匹配类型,兼容异常场景,代码可维护性高
  • 后续使用时通过switch匹配枚举case即可安全取值,不会出现类型转换崩溃问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:36:03