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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 23:50:35