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

JSON响应中Key类型随机为Int/String时的解析方案求助

解析JSON中类型随机为Int/String的字段

原代码失效原因

你原来的写法存在两个核心问题:

  1. catch块内直接调用try container.decode(String.self, forKey: .Quantity),若这次解码仍失败(比如字段不存在、类型仍不匹配),会直接抛出错误中断整个解码流程;
  2. 第一次decode(Int.self)失败后,container内部的读取指针可能已偏移,导致后续无法正确读取目标Key的数据。

可行解决方案

方案一:用try?尝试双类型解析

直接在初始化方法中依次尝试解析为Int或String,处理结果后转为目标格式:

struct YourModel: Decodable {
    var Quantity: String?
    
    enum CodingKeys: String, CodingKey {
        case Quantity
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 优先尝试解析为Int
        if let intVal = try? container.decode(Int.self, forKey: .Quantity) {
            Quantity = intVal == 0 ? nil : String(intVal)
        }
        // 尝试解析为String
        else if let strVal = try? container.decode(String.self, forKey: .Quantity) {
            // 可根据需求处理空字符串或"0"的情况
            Quantity = strVal.isEmpty || strVal == "0" ? nil : strVal
        }
        // 两种类型都不匹配时,可选择设为nil或抛出错误
        else {
            Quantity = nil
            // throw DecodingError.typeMismatch(Any.self, DecodingError.Context(codingPath: [CodingKeys.Quantity], debugDescription: "字段类型应为Int或String"))
        }
    }
}

方案二:用枚举包装双类型(更规范)

定义兼容Int和String的枚举,解码后再转换为目标类型:

// 定义兼容Int/String的枚举
enum IntOrString: Decodable {
    case int(Int)
    case string(String)
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let intVal = try? container.decode(Int.self) {
            self = .int(intVal)
        } else if let strVal = try? container.decode(String.self) {
            self = .string(strVal)
        } else {
            throw DecodingError.typeMismatch(IntOrString.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected Int or String"))
        }
    }
}

// 业务模型
struct YourModel: Decodable {
    var Quantity: String?
    
    enum CodingKeys: String, CodingKey {
        case Quantity
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let value = try container.decode(IntOrString.self, forKey: .Quantity)
        
        switch value {
        case .int(let intVal):
            Quantity = intVal == 0 ? nil : String(intVal)
        case .string(let strVal):
            Quantity = strVal.isEmpty || strVal == "0" ? nil : strVal
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:22:43