如何在 Swift 中创建一个返回可解码类型的函数?



所以我有这个枚举,我用于我在应用程序中使用的几个 url 请求:

enum Netwrok {
case popular
case topRated
case latest
// ...
static let baseUrl = "http://..."
func path() -> String {
switch self {
case .popular: return "/popular"
// ...
}
}
}

我想添加一个函数,该函数返回网络堆栈应用来解码数据的模型的可解码类型。

所以我认为这样的事情可以完成这项工作:

func returnType<T>() -> T.Type where T : Decodable {
switch self {
case .popular:
return Popular.self
// ...
}
}

但我不能让它工作,它说:

无法将类型为"Popular.Type"的返回表达式转换为返回类型"T.Type">

要我强行投T.Type.

如何创建一个返回可解码的函数,以便可以处理该类型,但 JSONDecoder 的解码函数?

谢谢。

你问的很简单,但可能不是你想要的。您要求做的是返回一个类型。这没有什么通用的。

func returnType<T>() -> T.Type where T : Decodable {

此语法定义由调用方传递的类型参数T。它不是由你的函数定义的。这意味着调用方可以传递任何可解码的类型,并且您的函数将返回它。例如,调用方可以将T设置为 Int(因为它是可解码的(,您将返回Int.Type。这很容易实现(return T.self(,但不是你的意思。

你的意思是,该函数返回函数知道的某种可解码的类型,但调用方不知道:

func returnType() -> Decodable.Type { ... }

这将正常工作,并且完全符合您的要求,但它表明您可能不正确地构建了此网络堆栈,并且以后会感到头疼。

这种方法可能是一个问题的原因是,您可能希望编写如下代码行:

let result = JSONDecoder().decode(networkType.returnType(), from: data)

这将中断,因为Decodable.Type本身不是可解码的类型。(您解码 Int,但无法解码Int 的类型。说它确实有效。result会是什么类型?你能用它做什么?你唯一知道的是它是可解码的(而且你已经解码了它(。

你可能想要更像Vasu Chand的实现,或者我的博客系列中讨论的类似方法。

您可以将转义闭包用于 API 调用的返回结果。

假设您正在点击一个 get 请求。一个简单的工作示例,用于传递获取请求 API 的可编码模型。

class func GETRequest<ResponseType :Decodable>(url : URL,responseType : ResponseType.Type ,completion: @escaping (ResponseType? ,Error? ) -> Void){

var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else{
completion(nil,error)
return
}
let decoder = JSONDecoder()
do{
let responseData = try decoder.decode(ResponseType.self, from: data)
completion(responseData, nil)
}
catch let error{
completion(nil, error)

}
}
task.resume()   
}

如何调用此网络函数。

Network.GETRequest(url: url, responseType: Model.self) { (model, error) in
completion(model,error)
}

模型类包含

struct Model : Codable{
}

您可以将任何get请求的任何响应模型传递给网络类。

同样,您可以为post请求构建api网络,其中请求正文只是可编码的模型。

抱歉,您不能

根据需要在此处提供第一个参数
JSONDecoder().decode(AdecodableType.self,from:data)

需要在编写代码时正确推断,以便它不能是符合Decodable的类型集合中的任何 1

相关内容

  • 没有找到相关文章

最新更新