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

Swift 4 Decodable处理包含多种类型的JSON数组

刚好之前做项目时遇到过一模一样的场景!用Swift 4+的Decodable处理混合类型数组,最靠谱的方式就是用枚举来封装不同的模型,通过数据里的标识字段(比如你JSON里的type)来判断该解析成哪种类型。下面给你一步步讲怎么实现:

1. 先定义具体的模型结构

首先把Member和ImageMedium这两个基础模型写好,各自遵守Decodable协议,对应它们的专属字段:

struct Member: Decodable {
    let id: String
    // 这里根据你的实际业务需求添加Member的其他字段,比如name、avatarUrl等
    // 如果你需要处理像`owner-id`这种蛇形命名的字段,后面可以用解码器的策略自动转换
}

struct ImageMedium: Decodable {
    let id: String
    // 同样添加ImageMedium的专属字段,比如imageUrl、width、height等
}
2. 用枚举封装混合类型

创建一个枚举(比如叫DataItem)来统一管理这两种类型,关键是要实现自定义的init(from decoder:)方法,根据type字段的值来决定解析成哪种模型:

enum DataItem: Decodable {
    case member(Member)
    case imageMedium(ImageMedium)
    
    // 只定义用来判断类型的CodingKey
    enum CodingKeys: String, CodingKey {
        case type
    }
    
    init(from decoder: Decoder) throws {
        // 先解析出type字段的值
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let itemType = try container.decode(String.self, forKey: .type)
        
        // 根据type值匹配对应的模型
        switch itemType {
        case "member":
            let memberModel = try Member(from: decoder)
            self = .member(memberModel)
        case "imageMedium": // 这里要和你JSON里ImageMedium对应的type值完全一致
            let imageModel = try ImageMedium(from: decoder)
            self = .imageMedium(imageModel)
        default:
            // 遇到未知类型时,可以抛出错误或者做默认处理
            throw DecodingError.dataCorruptedError(
                forKey: .type,
                in: container,
                debugDescription: "Unsupported item type: \(itemType)"
            )
        }
    }
}
3. 定义顶层响应模型

对应你给出的JSON结构,顶层是一个包含data数组的对象,所以定义一个顶层模型来承接:

struct ApiResponse: Decodable {
    let data: [DataItem]
}
4. 执行解析并处理结果

现在就可以正常解析JSON数据了,比如从网络请求返回的Data对象解析:

// 假设jsonData是你拿到的JSON数据
let jsonData: Data = ...

do {
    let decoder = JSONDecoder()
    // 如果你需要处理蛇形命名的字段(比如`owner-id`),打开下面这行
    // decoder.keyDecodingStrategy = .convertFromSnakeCase
    
    let response = try decoder.decode(ApiResponse.self, from: jsonData)
    
    // 遍历数组,分别处理不同类型的对象
    for item in response.data {
        switch item {
        case .member(let member):
            print("处理Member对象,ID:\(member.id)")
            // 这里写你的Member业务逻辑
        case .imageMedium(let image):
            print("处理ImageMedium对象,ID:\(image.id)")
            // 这里写你的ImageMedium业务逻辑
        }
    }
} catch {
    print("解析出错:\(error.localizedDescription)")
}
额外提示
  • 一定要确保switch里的type字符串和JSON里的完全匹配(大小写敏感),比如如果你的ImageMedium对应的type是"image",那就要改成case "image"。
  • 如果需要兼容更多类型,只需要给枚举添加新的case,并在init方法里补充对应的判断逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:39:54