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

iOS Swift中如何实现含模糊类型的JSON属性解码?

Swift JSON解码:混合类型数组映射到枚举模型

要把给定的JSON数据解码到目标Swift模型,核心是处理pattern数组里的混合类型——单个整数和双元素整数数组,分别对应CardPattern的两个枚举case。以下是完整实现:

完整解码代码

import Foundation

struct Card: Decodable {
    let identifier: String
    let issuer: String
    let pattern: [CardPattern]
}

enum CardPattern: Decodable {
    case prefix(Int)
    case range(start: Int, end: Int)
    
    // 自定义解码逻辑
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        
        // 先尝试解码单个Int,对应prefix case
        if let prefixValue = try? container.decode(Int.self) {
            self = .prefix(prefixValue)
            return
        }
        
        // 尝试解码双元素数组,对应range case
        if let rangeValues = try? container.decode([Int].self), rangeValues.count == 2 {
            self = .range(start: rangeValues[0], end: rangeValues[1])
            return
        }
        
        // 不符合两种类型时抛出解码错误
        throw DecodingError.dataCorruptedError(in: container, debugDescription: "Unsupported pattern type")
    }
}

// 测试解码
let jsonData = """
{
   "identifier": "1",
   "issuer": "visa",
   "pattern": [5, [7, 9]]
}
""".data(using: .utf8)!

do {
    let card = try JSONDecoder().decode(Card.self, from: jsonData)
    print("解码成功:")
    print("identifier: \(card.identifier)")
    print("issuer: \(card.issuer)")
    print("pattern: \(card.pattern)")
} catch {
    print("解码失败:\(error)")
}

代码说明

  • CardPattern枚举通过实现init(from decoder: Decoder)方法,处理两种JSON输入:
    1. 先尝试解码为单个Int,成功则返回.prefix case
    2. 若失败,尝试解码为[Int],且数组长度必须为2,成功则返回.range case
    3. 若都不符合,抛出解码错误
  • Card结构体无需额外自定义解码逻辑,因为其所有属性都遵循Decodable协议([CardPattern]的可解码性由CardPattern的实现保证)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:39:53