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

Swift使用Alamofire解析JSON时的序列化错误与属性访问问题

解决JSON序列化错误的问题

嘿,我帮你排查一下这个序列化的问题,咱们先从错误提示入手:

Error serialization: typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

这个错误很明确:你告诉JSONDecoder要解码一个数组([Description].self),但返回的JSON根结构是一个字典(外层是{"data": [...]}),这就导致了类型不匹配。接下来咱们一步步修正代码:

1. 修正结构体定义(遵循Swift规范+匹配JSON结构)

首先,Swift中类型名要首字母大写,而且你的data结构体和Foundation的Data类型重名了,建议改成更有意义的名字,比如Category。另外,你的Description结构体里的_data属性和JSON里的data键不匹配,需要调整:

import Foundation
import Alamofire

// 根结构体,对应JSON外层的字典
struct ApiResponse: Decodable {
    let data: [Category] // 和JSON里的"data"键直接对应
}

// 对应数组里的每个分类元素
struct Category: Decodable {
    let id: Int?
    let descricao: String?
    let urlImagem: String?
}

如果坚持要用_data作为属性名,也可以通过CodingKeys来做键名映射:

struct ApiResponse: Decodable {
    let _data: [Category]
    
    enum CodingKeys: String, CodingKey {
        case _data = "data"
    }
}

2. 修正解码逻辑

因为JSON根是单个字典,所以要解码成ApiResponse.self,而不是数组类型:

func callApi() {
    guard let url = URL(string: "https://alodjinha.herokuapp.com/categoria") else { return }
    Alamofire.request(url).responseData { response in // 用responseData更直接,避免额外转换
        guard let data = response.data else { return }
        do {
            let parsedResponse = try JSONDecoder().decode(ApiResponse.self, from: data)
            // 现在可以访问所有数据了,比如遍历打印每个分类
            for category in parsedResponse.data {
                print("ID: \(category.id ?? 0), 描述: \(category.descricao ?? "无"), 图片URL: \(category.urlImagem ?? "无")")
            }
            // 或者单独访问某个元素的属性
            if let firstCategory = parsedResponse.data.first {
                print(firstCategory.id)
            }
        } catch {
            print("序列化错误: \(error.localizedDescription)")
        }
    }
}

关键修正点总结

  • 类型匹配:JSON根是字典结构,所以要解码成单个结构体实例,而非数组
  • 属性名匹配:确保结构体的属性名和JSON的键完全一致,或者用CodingKeys做映射
  • 命名规范:Swift类型首字母大写,避免和系统内置类型(比如Data)重名

这样修改后,你就能正常访问data数组里的所有属性啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:56:45