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

如何将API获取的字段设为可选?Swift解码报错排查

解决Swift JSON解码中可选字段类型不匹配的问题

从你给出的报错信息来看,问题的核心不是「字段设为可选」,而是类型完全不匹配:你的结构体里把dates定义成了字典类型([String: Any]?),但API返回的却是一个数组(哪怕是空数组[])。可选属性只是允许字段值为nil,但不能接受类型完全不同的数据,所以才会抛出typeMismatch错误。

下面给你两种针对性的解决方案:

1. 确认API字段类型,修正结构体定义

如果API文档里dates字段的正确类型就是数组(比如存储多个日期字典),直接把结构体里的dates类型改成数组可选即可:

// 假设你的上层结构体是这样
struct Event: Decodable {
    // 其他字段...
    let dates_timing: [EventTiming]?
}

// 修正后的EventTiming结构体
struct EventTiming: Decodable {
    // 把原来的 [String: Any]? 改成 [[String: Any]]?
    let dates: [[String: Any]]?
}

这样无论API返回空数组[]还是有内容的数组,都能正常解码,空数组会被解析成[]而非nil,如果字段完全缺失才会是nil。

2. 处理API返回混合类型的情况(字典/数组随机出现)

如果API存在不规范的情况——dates有时返回单个字典,有时返回数组,那需要自定义解码逻辑来兼容两种类型:

struct EventTiming: Decodable {
    // 统一用数组类型存储,单个字典会被包装成单元素数组
    let dates: [[String: Any]]?

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        do {
            // 优先尝试解码成数组
            dates = try container.decodeIfPresent([[String: Any]].self, forKey: .dates)
        } catch DecodingError.typeMismatch {
            // 类型不匹配时,尝试解码成单个字典,再包装成数组
            if let singleDateDict = try container.decodeIfPresent([String: Any].self, forKey: .dates) {
                dates = [singleDateDict]
            } else {
                // 两种解码都失败,设为nil
                dates = nil
            }
        }
    }
    
    enum CodingKeys: String, CodingKey {
        case dates
    }
}

这个逻辑会先尝试按数组解码,失败后再尝试按单个字典解码,把单个字典转成数组,保证无论API返回哪种格式,都能正确解析。

最后建议你优先和后端团队确认API字段的规范类型,避免因为接口返回不一致导致后续的兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:00:29