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

Swift解析JSON报错typeMismatch:期望Dictionary<String, Any>却找到数组求助

报错原因
  • 第一层原因:Carrusel 结构体中定义的 videoUrl 为非可选字符串类型,但你提供的接口返回数据里,多个 Carrusel 元素没有返回 videoUrl 字段,导致 [CarruselesData] 解析直接失败。
  • 第二层原因:成功响应解析失败后,你的代码直接尝试将返回内容解码为 CarruselesErrorResponse 类型,该类型应为字典结构,但接口本次返回的是成功的数组结构,用字典类型解码数组就触发了你看到的类型不匹配报错。

另外你的代码中存在冗余逻辑:JSONSerialization.jsonObject(with: unwrappedData, options: []) 这行代码的返回值没有被使用,可以直接删除。

修复方案

第一步:调整模型字段可选性

将接口可能缺失的 videoUrl 字段改为可选类型:

struct Carrusel: Codable {
    let title: String
    let imageUrl: String
    let videoUrl: String? // 改为可选类型,允许字段缺失
    let description: String
}

struct CarruselesData: Codable {
    let title: String
    let type: String
    let items: [Carrusel]
}

第二步:优化解析逻辑,区分成功/错误响应场景

新增HTTP状态码判断,仅2xx成功状态码下解析成功响应,其他状态码再解析错误响应,避免类型匹配错误:

func getCarruseles(completion: @escaping (Result<[CarruselesData], Error>)-> Void) {
    let urlString =  baseUrl + "url"
    guard let url = URL(string: urlString) else {
        completion(.failure(NetworkingError.badUrl))
        return
    }
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.setValue("Bearer token", forHTTPHeaderField: "Authorization")
    let session = URLSession.shared

    let task = session.dataTask(with: request) { (data, response, error) in
        DispatchQueue.main.async {
            // 处理系统级错误
            if let unwrappedError = error {
                completion(.failure(unwrappedError))
                return
            }
            // 校验HTTP响应状态码
            guard let httpResponse = response as? HTTPURLResponse else {
                completion(.failure(NetworkingError.invalidResponse))
                return
            }
            // 非2xx状态码走错误响应解析逻辑
            guard (200...299).contains(httpResponse.statusCode) else {
                if let data = data, let errorRes = try? JSONDecoder().decode(CarruselesErrorResponse.self, from: data) {
                    print("接口错误:\(errorRes)")
                    completion(.failure(errorRes))
                } else {
                    completion(.failure(NetworkingError.invalidResponse))
                }
                return
            }
            // 2xx状态码走成功响应解析逻辑
            guard let unwrappedData = data else {
                completion(.failure(NetworkingError.emptyData))
                return
            }
            do {
                let successRes = try JSONDecoder().decode([CarruselesData].self, from: unwrappedData)
                completion(.success(successRes))
            } catch {
                print("成功响应解析失败:\(error)")
                completion(.failure(error))
            }
        }
    }
    task.resume()
}

如果你的 NetworkingError 枚举没有 invalidResponse、emptyData 类型,可以自行补充,或者替换为你现有可用的错误类型即可。

内容的提问来源于stack exchange,提问作者Edward Pizzurro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:36:06