所以我有这个枚举,可用于我在应用程序中使用的几个url请求:
enum Netwrok {
case popular
case topRated
case latest
// ...
static let baseUrl = "http://..."
func path() -> String {
switch self {
case .popular: return "/popular"
// ...
}
}
}
而且我想添加一个函数,该函数返回网络堆栈应使用其解码数据的模型的Decodable Type。
所以我认为类似的事情可以完成工作:
func returnType<T>() -> T.Type where T : Decodable {
switch self {
case .popular:
return Popular.self
// ...
}
}
但是我无法使它起作用,它说:
无法将类型'Popular.Type'的返回表达式转换为类型'T.Type'
要求我强制使用T.Type
。
我如何制作一个返回可解码的函数,以便可以处理类型,但可以使用JSONDecoder的解码函数?
谢谢。
您可以将转义闭包用于API调用的返回结果。
假设您正在点击获取请求。一个简单的工作示例,用于将Codable模型传递给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)
}
Model类包含
struct Model : Codable{
}
您可以将对任何get
请求的任何响应模型传递给网络类。
类似地,您可以为请求后的请求构建api网络,其中请求主体只是可编码的模型。
对不起,您不能根据您的需要在此处提供第一个参数
JSONDecoder().decode(AdecodableType.self,from:data)
在编写代码时需要正确推断,因此它不能是符合Decodable
的类型集合中的Any 1
您要问的很简单,但可能不是您想要的。您要执行的操作是返回一个类型。没有什么通用的。
func returnType<T>() -> T.Type where T : Decodable {
此语法定义了类型参数T
,由caller传递。它不是由您的函数定义的。这意味着调用方可以传递可解码的any类型,您的函数将返回它。例如,呼叫者可以将T
设置为Int(因为它是可解码的),然后您将返回Int.Type
。这很容易实现(return T.self
),但不是您的意思。
您的意思是该函数返回该函数知道的某种可解码的类型,但调用者却不知道:
func returnType() -> Decodable.Type { ... }
这可以很好地工作,并且可以完全满足您的要求,但这表明您可能不正确地构建了此网络堆栈,以后会头疼。
这种方法可能会出现问题的原因是,您可能想编写如下代码:
let result = JSONDecoder().decode(networkType.returnType(), from: data)
这将中断,因为Decodable.Type
不是itself可解码的类型。 (您对Int进行了解码,但无法对Int的type进行解码。)说它确实有效。 result
是什么类型?您能用它做什么?
您可能想要更多类似Vasu Chand的实现,或the similar approach discussed in my blog series。