Swift中泛型结合JSON Encoder使用时类型不匹配报错问题
解决Swift POST请求中泛型类型不匹配的问题
错误原因
你的sendPostRequest函数仅定义了单个泛型参数T,强制要求请求参数params和响应类型responseType必须为同一个T类型。但调用时你传入的params是AddPostModel.AddPostRequest,responseType是AddPostModel.AddPostResponse,二者为不同结构体,因此触发类型不匹配错误。
解决方案:拆分泛型参数
修改sendPostRequest函数,定义两个独立的泛型参数,分别对应请求参数类型和响应类型,支持请求与响应类型不同的通用场景:
// 确保你已定义以下枚举 enum HTTPError: Error { case invalidUrl case failedResponse } enum HTTPMethods { case POST var method: String { switch self { case .POST: return "POST" } } } func sendPostRequest<Request: Codable, Response: Codable>( url: String, responseType: Response.Type, params: Request ) async -> Result<Response, Error> { do { let session = URLSession(configuration: .default) guard let url = URL(string: url) else { return .failure(HTTPError.invalidUrl) } var request = URLRequest(url: url) request.httpMethod = HTTPMethods.POST.method // 新增Content-Type头,确保服务器正确解析JSON request.setValue("application/json", forHTTPHeaderField: "Content-Type") let jsonData = try JSONEncoder().encode(params) request.httpBody = jsonData let (data, response) = try await session.data(for: request) guard let urlResponse = response as? HTTPURLResponse, (200...299).contains(urlResponse.statusCode) else { return .failure(HTTPError.failedResponse) } let jsonResponse = try JSONDecoder().decode(responseType.self, from: data) return .success(jsonResponse) } catch { return .failure(error) } }
调用修改后的函数
此时addPost函数可正常调用,类型匹配不再报错:
func addPost(params: AddPostModel.AddPostRequest) async -> Result<AddPostModel.AddPostResponse, Error> { return await service.sendPostRequest( url: Constant.BASE_URL + "/" + HomeEndPoints.posts.path, responseType: AddPostModel.AddPostResponse.self, params: params ) }
额外优化建议
由于你的请求与响应结构完全一致,可合并两个结构体减少冗余代码:
enum AddPostModel { struct AddPost: Codable { let title: String let body: String let userId: String let id: String } } // 调用时直接复用同一类型 func addPost(params: AddPostModel.AddPost) async -> Result<AddPostModel.AddPost, Error> { return await service.sendPostRequest( url: Constant.BASE_URL + "/" + HomeEndPoints.posts.path, responseType: AddPostModel.AddPost.self, params: params ) }
内容的提问来源于stack exchange,提问作者user11640506
相关产品推荐
相关产品推荐

