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

Moya解码JSON报错:期望数组却得到字典,求助解决

问题解决:Expected to decode Array but found a dictionary instead

错误根源

你遇到的解码错误,核心原因是JSON数据与Swift结构体类型不匹配:

  • JSON中第二个button的actions字段是单个字典对象({...})
  • 但你的RequestButtons结构体里,actions被定义为数组类型[RequestButtons]?

解码器期望解析数组,实际拿到字典,因此抛出错误。

直接解决方案

将RequestButtons结构体中的actions类型从数组改为单个可选对象:

struct RequestButtons: Codable {
    let name: RequestButtonName
    let title: String
    let active: Bool?
    let actions: RequestButtons? // 从[RequestButtons]?改为RequestButtons?
    let paymentLink: String?
    let paymentContext: String?
    let value: String?
    let badge: Int?
}

修改后,解码器就能正确匹配JSON中的字典类型,完成解码。

兼容数组/单个对象的进阶方案

如果后端存在actions字段有时返回数组、有时返回单个对象的情况,可以通过自定义解码逻辑处理两种场景:

struct RequestButtons: Codable {
    let name: RequestButtonName
    let title: String
    let active: Bool?
    let actions: [RequestButtons]? // 保持数组类型,自定义解码逻辑
    let paymentLink: String?
    let paymentContext: String?
    let value: String?
    let badge: Int?
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        name = try container.decode(RequestButtonName.self, forKey: .name)
        title = try container.decode(String.self, forKey: .title)
        active = try container.decodeIfPresent(Bool.self, forKey: .active)
        paymentLink = try container.decodeIfPresent(String.self, forKey: .paymentLink)
        paymentContext = try container.decodeIfPresent(String.self, forKey: .paymentContext)
        value = try container.decodeIfPresent(String.self, forKey: .value)
        badge = try container.decodeIfPresent(Int.self, forKey: .badge)
        
        // 处理actions的两种情况:单个对象或数组
        do {
            // 先尝试解码为单个对象,然后包装成数组
            let singleAction = try container.decode(RequestButtons.self, forKey: .actions)
            actions = [singleAction]
        } catch {
            // 如果失败,尝试解码为数组
            actions = try container.decodeIfPresent([RequestButtons].self, forKey: .actions)
        }
    }
    
    enum CodingKeys: String, CodingKey {
        case name, title, active, actions, paymentLink, paymentContext, value, badge
    }
}

这样无论后端返回单个字典还是数组,解码器都能正确处理。


内容的提问来源于stack exchange,提问作者Mikl.hart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:20:16