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
相关产品推荐
相关产品推荐

