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错误,说明返回的是单个字符串,此时将其转为单元素数组即可。 - 该方案同时兼容服务器返回的两种格式,避免解码失败。
验证示例
当返回
message为数组时:{ "statusCode": 400, "message": ["用户名不能为空", "密码长度不足"], "error": "Bad Request" }解码后
message值为["用户名不能为空", "密码长度不足"]。当返回
message为单个字符串时:{ "statusCode": 401, "message": "未授权访问", "error": "Unauthorized" }解码后
message值为["未授权访问"]。
内容的提问来源于stack exchange,提问作者Mohamed Said
相关产品推荐
相关产品推荐

