如何在 swift 中将泛型与 JSON 编码器一起使用

How to use Generics with JSON Encoder in swift

提问人:user11640506 提问时间:11/5/2023 最后编辑:Alexanderuser11640506 更新时间:11/6/2023 访问量:54

问:

我正在使用 JSON 占位符 post api 使用 Swift 中的泛型和结果类型发出 HTTP POST 请求。这是我用于请求和响应的可编码结构。对于此 API,响应和请求是相同的。

enum AddPostModel{
    struct AddPostRequest: Codable{
        let title: String
        let body: String
        let userId: String
        let id: String
    }
    struct AddPostResponse: Codable{
        let title: String
        let body: String
        let userId: String
        let id: String
    }
}

这是我使用 URLSession async/await、泛型和结果类型的 POST 请求代码。

func sendPostRequest<T: Codable>(url: String,responseType: T.Type,params: T) async -> Result<T,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
            
            
            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)
        }
    }

这里我调用 Post 方法

 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)
    }

当我尝试构建时,我在 sendPostRequest 方法的 params 参数中出现以下错误

无法将类型的值转换为预期的参数类型AddPostModel.AddPostRequestAddPostModel.AddPostResponse

JSON Swift 泛型 URLSessage

评论

1赞 vadian 11/6/2023
两种类型是相同的。你为什么要把事情复杂化?AddPost…

答:

2赞 son 11/5/2023 #1

您对请求和响应使用相同的泛型,这是不可能的。泛型参数是指具有可选约束的占位符类型,这些约束将在编译时被替换,并且它们不能是同一上下文中的两种不同类型。声明另一个泛型类型(如 for 请求参数)将解决此问题。TU

func sendPostRequest<T: Codable, U: Codable>(url: String, responseType: T.Type, params: U) async -> Result<T, Error> {
    ...
}