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

iOS 13+ Swift嵌套对象自定义JSON解码器实现方案

iOS 13+ 兼容的嵌套JSON解码方案(依赖父对象type字段)

问题场景

JSON响应包含type字段(值为email或telephone),嵌套的content.attributes结构随type变化,需在解码content时依赖父对象的type值,且需兼容iOS 13+,无法使用iOS 15+的CodableWithConfiguration。

实现步骤

1. 定义类型枚举与属性模型

先明确响应类型和对应属性结构:

// 响应类型枚举
enum ResponseType: String, Codable {
    case email, telephone
}

// Email类型对应的属性模型
struct EmailAttributes: Codable {
    let emailAddress: String
    let isPrimary: Bool
}

// Telephone类型对应的属性模型
struct TelephoneAttributes: Codable {
    let phoneNumber: String
    let countryCode: String
}

2. 定义可解码的ContentResponse枚举

用枚举封装不同类型的属性,通过自定义初始化方法接收父对象的type参数:

enum ContentResponse: Codable {
    case email(EmailAttributes)
    case telephone(TelephoneAttributes)
    
    // 接收type参数的自定义解码初始化
    init(type: ResponseType, from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        switch type {
        case .email:
            let attrs = try container.decode(EmailAttributes.self)
            self = .email(attrs)
        case .telephone:
            let attrs = try container.decode(TelephoneAttributes.self)
            self = .telephone(attrs)
        }
    }
    
    // 编码方法(若需编码可实现,此处省略核心逻辑)
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .email(let attrs): try container.encode(attrs)
        case .telephone(let attrs): try container.encode(attrs)
        }
    }
}

3. 父对象Response自定义解码逻辑

在父对象解码时先获取type,再将其传递给ContentResponse完成解码:

struct Response: Codable {
    let type: ResponseType
    let content: ContentResponse
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        // 优先解码type字段
        self.type = try container.decode(ResponseType.self, forKey: .type)
        // 获取content字段的专属解码器,传递type解码ContentResponse
        let contentDecoder = container.superDecoder(forKey: .content)
        self.content = try ContentResponse(type: self.type, from: contentDecoder)
    }
    
    enum CodingKeys: String, CodingKey {
        case type, content
    }
}

方案说明

  • 完全兼容iOS 13+:所有API均为Swift 5.1+(iOS 13对应Swift版本)支持的标准Codable扩展,无系统版本限制。
  • 逻辑清晰:父对象先解码关键的type字段,再通过superDecoder为子对象创建独立解码上下文,将type参数传递给子对象的自定义初始化,实现基于父字段的动态解码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:12:17