我使用泛型编写了一种方法,以使其可重用于任何类型的下载。它下载json数组并返回通用对象或错误。 这是我的从服务器下载json数组的类:
import Foundation
enum Result<T> {
case success(T)
case failure(Error)
}
class LTLNetworkClient: NSObject {
fileprivate var session : URLSession
fileprivate var objectTask : URLSessionDataTask?
override init() {
let config = URLSessionConfiguration.ephemeral
config.timeoutIntervalForResource = 5
config.timeoutIntervalForRequest = 5
self.session = URLSession.init(configuration: config)
}
/**
Download asynchronously json object from Server and returns it into generic data models
*/
func getData<K: Codable>(request: URLRequest, completion: @escaping (Result<[K]>) -> Void) {
let sessionDataTask = URLSession.shared.dataTask(with: request) { (responseData, response, responseError) in
if let jsonData = responseData {
let decoder = JSONDecoder()
do {
let response = try decoder.decode([K].self, from: jsonData)
let result: Result<[K]> = Result.success(response)
completion(result)
} catch {
completion(.failure(error))
}
} else if let error = responseError {
completion(.failure(error))
} else {
let error = NSError(domain: "Cannot form jsonData with Response Data", code: 501, userInfo: nil)
completion(.failure(error))
}
}
sessionDataTask.resume()
}
}
这就是我调用方法和得到的错误的方式:
有人知道如何解决它,为什么会出现此错误? 提前很多
答案 0 :(得分:2)
这是您的方法声明:
scale_x_continuous
此方法具有类型参数func getData<K: Codable>(request: URLRequest, completion: @escaping (Result<[K]>) -> Void)
,仅在K
参数的类型中使用。当编译器看到对completion
的调用时,它必须根据您作为getData
传递的闭包的参数类型来推导K
的具体类型。
这是您的电话:
completion
在此调用中,networkClient.getData(request: urlRequest) { (result) in
// Do stuff
}
闭包为completion
。 { (result) in }
是什么类型?没有给出任何相关信息,因此编译器只知道对于某些类型result
,result
必须是类型Result<[K]>
。它无法推断K
的具体类型,因此会产生错误。
您可以像这样使类型明确:
K
其中networkClient.getData(request: urlRequest) { (_ result: Result<[SomeConcreteCodableType]>) -> Void in
// Do stuff
}
是符合SomeConcreteCodableType
的某种具体类型。由于Codable
的声明存在约束,因此需要Codable
一致性。
另一种解决方案是更改getData
以采用另一个参数,该参数可让调用者直接指定getData
:
K
然后您这样称呼它:
func getArray<K: Codable>(of: K.Type, for request: URLRequest,
completion: @escaping (Result<[K]>) -> Void) {
...
}