使用Codable协议处理API请求遇类型转换错误求助
首先咱们理清问题根源:你遇到的类型不匹配错误,是因为网络请求的完成闭包期望接收数组类型(比如Either<[Item]>),但你试图传入接收嵌套类型(Either<NestedType>)的闭包,两者类型不兼容导致的。下面一步步给你解决思路和代码示例:
1. 确保Codable嵌套结构正确
首先要定义完全匹配API返回结构的嵌套模型。API返回的是包含results键的对象,里面是条目数组,所以模型应该这样写:
// 单个条目模型 struct Item: Codable { let id: String } // 嵌套的响应模型(对应你说的NestedType/TestResponse) struct TestResponse: Codable { let results: [Item] }
注意:你给出的示例JSON{ results: ["id": "1", "id": "2"] }存在语法错误,正确的JSON结构应该是{ "results": [{"id": "1"}, {"id": "2"}] }——results对应的值是一个对象数组,每个对象包含id字段,上面的模型正好匹配这个结构。
2. 调整网络请求的泛型类型
问题核心在于你的网络请求方法的泛型参数。如果之前你是直接用[Item]作为解析目标(比如请求方法定义为fetchItems(completion: (Either<[Item]>) -> Void)),现在必须把泛型参数改成TestResponse,让请求方法明确要解析的是整个嵌套对象,而非直接解析数组。
举个基于URLSession的自定义请求示例:
// 假设你用这个自定义Either枚举处理成功/失败结果 enum Either<Success> { case success(Success) case failure(Error) } // 调整后的网络请求方法,泛型参数改为TestResponse func fetchItems(completion: @escaping (Either<TestResponse>) -> Void) { guard let url = URL(string: "你的API地址") else { completion(.failure(NSError(domain: "InvalidURL", code: 0))) return } URLSession.shared.dataTask(with: url) { data, _, error in if let error = error { completion(.failure(error)) return } guard let data = data else { completion(.failure(NSError(domain: "EmptyData", code: 0))) return } do { // 这里用TestResponse.self解析,替换原来的[Item].self let response = try JSONDecoder().decode(TestResponse.self, from: data) completion(.success(response)) } catch { completion(.failure(error)) } }.resume() }
3. 正确调用请求方法
现在调用这个请求方法时,闭包的参数类型会完全匹配Either<TestResponse>,不会再出现类型转换错误:
fetchItems { result in switch result { case .success(let response): // 从嵌套模型中取出results数组进行后续处理 let items = response.results print("获取到条目:\(items)") // 这里可以遍历items做业务逻辑处理 case .failure(let error): print("请求失败:\(error.localizedDescription)") } }
总结
你之前的错误本质是请求解析目标和闭包接收类型不匹配——原本请求直接解析数组,现在要解析包含数组的嵌套对象,所以必须同步修改请求的泛型参数,让它对应你的嵌套Codable类型,这样闭包参数类型就会完全对齐,错误也就解决了。
内容的提问来源于stack exchange,提问作者Brian Marsh

