如何在Swift中使用JSON编码器的泛型

rvpgvaaj  于 2023-11-16  发布在  Swift
关注(0)|答案(1)|浏览(135)

我使用JSON Placeholder 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
    }
}

字符串
下面是我的POST请求代码,使用了URLSession_await/await,泛型和结果类型。

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.AddPostRequest的值转换为预期的参数类型AddPostModel.AddPostResponse

bmvo0sr5

bmvo0sr51#

你对请求和响应都使用相同的泛型T,这是不可能的。泛型参数意味着一个占位符类型,带有可选的约束,这些约束将在编译时被替换,并且它们不能在同一上下文中是两个不同的类型。为请求参数声明另一个泛型类型,如U,将解决这个问题。

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

字符串

相关问题