为什么我的模板不适用于 JSONDecodable
Why doesn't my template work with JSONDecodable
我正在使用新的 Swift 4 Codable 接口从 Web 服务中简单地获取 JSON 数据。我试图实现一个通用类型方法来处理解码(因此我不需要自定义方法)但我一直收到错误。这是代码
extension StarWarsAPI {
public func decodeJson<T: Codable>(fetchUrl: URL, modelType: T, completion: @escaping (_ modelObject: Codable?, _ error:StarWarsErrorType?) -> Void){
//guard modelType is Codable else {return completion(nil,nil)}
var fetchRequest = URLRequest(url: fetchUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
fetchRequest.httpMethod = "GET"
fetchRequest.allHTTPHeaderFields = [
"content-type": "application/json",
"cache-control": "no-cache",
]
let session = URLSession.shared
let fetchDataTask = session.dataTask(with: fetchRequest) { (data, response, error) in
guard error == nil else {
return completion(nil, StarWarsErrorType.urlResponseError(error: error))
}
guard let httpResponse = response as? HTTPURLResponse else {
return completion(nil, StarWarsErrorType.NilUrlResponseError())
}
guard let data = data else {
return completion(nil, StarWarsErrorType.noDataFound)
}
guard httpResponse.statusCode > 199 && httpResponse.statusCode < 300 else {
return completion(nil, StarWarsErrorType.httpErrorCode(code: httpResponse.statusCode))
}
var modelObject:Codable?
do {
let jsonDecoder = JSONDecoder()
modelObject = try jsonDecoder.decode(modelType.self, from: data)
return completion(modelObject, nil)
}catch{ // do nothing }
DispatchQueue.main.async {
completion(nil, nil)
}
}
}
fetchDataTask.resume()
}
错误显示为 "Cannot invoke 'decode' with an argument list of type '(T, from: Data)'"。这是错误的屏幕截图。
我错过了什么?谢谢!
传递给decode(_:from:)
的类型需要静态知道。 modelType.self
是 modelType
的动态实例,但它的类型不受静态约束;您需要使用 T.self
,这是静态已知类型。
我正在使用新的 Swift 4 Codable 接口从 Web 服务中简单地获取 JSON 数据。我试图实现一个通用类型方法来处理解码(因此我不需要自定义方法)但我一直收到错误。这是代码
extension StarWarsAPI {
public func decodeJson<T: Codable>(fetchUrl: URL, modelType: T, completion: @escaping (_ modelObject: Codable?, _ error:StarWarsErrorType?) -> Void){
//guard modelType is Codable else {return completion(nil,nil)}
var fetchRequest = URLRequest(url: fetchUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
fetchRequest.httpMethod = "GET"
fetchRequest.allHTTPHeaderFields = [
"content-type": "application/json",
"cache-control": "no-cache",
]
let session = URLSession.shared
let fetchDataTask = session.dataTask(with: fetchRequest) { (data, response, error) in
guard error == nil else {
return completion(nil, StarWarsErrorType.urlResponseError(error: error))
}
guard let httpResponse = response as? HTTPURLResponse else {
return completion(nil, StarWarsErrorType.NilUrlResponseError())
}
guard let data = data else {
return completion(nil, StarWarsErrorType.noDataFound)
}
guard httpResponse.statusCode > 199 && httpResponse.statusCode < 300 else {
return completion(nil, StarWarsErrorType.httpErrorCode(code: httpResponse.statusCode))
}
var modelObject:Codable?
do {
let jsonDecoder = JSONDecoder()
modelObject = try jsonDecoder.decode(modelType.self, from: data)
return completion(modelObject, nil)
}catch{ // do nothing }
DispatchQueue.main.async {
completion(nil, nil)
}
}
}
fetchDataTask.resume()
}
错误显示为 "Cannot invoke 'decode' with an argument list of type '(T, from: Data)'"。这是错误的屏幕截图。
我错过了什么?谢谢!
传递给decode(_:from:)
的类型需要静态知道。 modelType.self
是 modelType
的动态实例,但它的类型不受静态约束;您需要使用 T.self
,这是静态已知类型。