Ios 通用参数';T';无法为网络层推断
我正在尝试创建一个通用网络层,并创建了一个Ios 通用参数';T';无法为网络层推断,ios,swift,generics,Ios,Swift,Generics,我正在尝试创建一个通用网络层,并创建了一个serviceheloperclass class ServiceHelper: NSObject { static let sharedInstance = ServiceHelper() func sendRequest<T: Decodable,Q: Encodable>(path: String, encodingData: Q, completion: @escaping(T?, Error?) -> Void) {
serviceheloperclass
class ServiceHelper: NSObject {
static let sharedInstance = ServiceHelper()
func sendRequest<T: Decodable,Q: Encodable>(path: String, encodingData: Q, completion: @escaping(T?, Error?) -> Void)
{
guard let url = URL(string: Constants.TEST_URL + path) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
do {
let jsonBody = try JSONEncoder().encode(encodingData)
request.httpBody = jsonBody
} catch { fatalError("JSON Body Failed")}
let task = URLSession.shared.dataTask(with: request) { (data,response, err) in
if let response = response {
print(response)
}
if let err = err {
print("Failed to fetch data:", err.localizedDescription, "Error Description\(err)")
return
}
guard let data = data else { return }
do {
print(String(data: data, encoding: String.Encoding.utf8) as Any)
let dataReceived = try JSONDecoder().decode(T.self, from: data)
completion(dataReceived,nil)
} catch let jsonErr {
print("Failed to serialize json:", jsonErr, jsonErr.localizedDescription)
completion( nil,jsonErr)
}
}
task.resume()
}
}
如何解决此错误?为什么我会犯这个错误?谁能帮帮我吗 在您的示例中,编译器无法知道解码的类型 解决方案是将解码类型添加为参数:
func sendRequest<T: Decodable,Q: Encodable>(path: String, encodingData: Q, decodedType: T.Type, completion: @escaping(T?, Error?) -> Void)
func sendRequest(路径:字符串,编码数据:Q,解码类型:T.Type,完成:@escaping(T?,Error?)->Void)
调用时,请使用WinningViewModel.self作为参数
同时确保WinningViewModel符合Decodable以匹配T要求
关于,编译器不知道您的
t
(输出可解码类型)
所以您需要提供输出类型,即可解码对象类型,就像下面的示例一样
不确定,但您是WinningViewModel
ServiceHelper.sharedInstance.sendRequest(path: "contest-winner-option",encodingData: encoded) { (response: WinningViewModel?, error) in
if let error = error {
print(error)
return
} else {
print(decoded)
}
}
希望它有帮助是的,我刚刚做了,现在正在测试。你也可以在类中作为方法编写它,因此,它的调用将通过
encoded….
进行推断,而不将类型作为参数发送。我猜这会起作用,但这与泛型相反principles@Sh_Khan我认为泛型类型没有违反规则。如果您可以解释一下,以便我可以在回答中进行更改,那么显式地执行:WinningViewModel?
是针对泛型的,被调用的方法应该使用它的own@Sh_Khan对不起,我想你对概念有点困惑。您的观点对于我不能直接使用:WinningViewModel?
的serviceheloper
类是绝对正确的,那么它就不再通用了。但是当我调用方法sendRequest
时,编译器确实需要知道什么是T
,什么是Q
。因此对于Q
我们已经通过了encoded
,但是对于T
我们需要提供输出类型,没有其他方法可以做到这一点。在创建initFetching
方法generic之前,假设使用typeX
并提供:X?
,但非常需要提供type,我已在参数中添加了type
,作为type:T.type
。它解决了这个问题。
ServiceHelper.sharedInstance.sendRequest(path: "contest-winner-option",encodingData: encoded) { (response: WinningViewModel?, error) in
if let error = error {
print(error)
return
} else {
print(decoded)
}
}