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

SwiftUI动态解码JSON:处理字符串/字符串数组字段

解决HTTPError中message字段的兼容解码问题

服务器返回的message字段类型不固定(既可能是字符串数组,也可能是单个字符串),默认Codable解码无法自动适配这种情况,需要通过自定义解码逻辑来处理:

实现自定义解码逻辑

修改HTTPError结构体,手动实现init(from decoder: Decoder)方法,兼容两种格式的message字段:

struct HTTPError: Codable {
    var statusCode: Int?
    var message: [String]
    var error: String?
    
    enum CodingKeys: String, CodingKey {
        case statusCode, message, error
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 常规解码固定类型字段
        statusCode = try container.decodeIfPresent(Int.self, forKey: .statusCode)
        error = try container.decodeIfPresent(String.self, forKey: .error)
        
        // 兼容处理message字段
        do {
            // 优先尝试解码为字符串数组
            message = try container.decode([String].self, forKey: .message)
        } catch DecodingError.typeMismatch {
            // 类型不匹配时,解码为单个字符串并包装成数组
            let singleMsg = try container.decode(String.self, forKey: .message)
            message = [singleMsg]
        }
    }
}

逻辑说明

  • 先按正常逻辑解码statusCode和error字段,这两个字段类型固定,无需特殊处理。
  • 对message字段,先尝试按数组类型解码;如果触发typeMismatch错误,说明返回的是单个字符串,此时将其转为单元素数组即可。
  • 该方案同时兼容服务器返回的两种格式,避免解码失败。

验证示例

  1. 当返回message为数组时:

    {
        "statusCode": 400,
        "message": ["用户名不能为空", "密码长度不足"],
        "error": "Bad Request"
    }
    

    解码后message值为["用户名不能为空", "密码长度不足"]。

  2. 当返回message为单个字符串时:

    {
        "statusCode": 401,
        "message": "未授权访问",
        "error": "Unauthorized"
    }
    

    解码后message值为["未授权访问"]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:10:33