Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 通用参数';T';无法为网络层推断_Ios_Swift_Generics - Fatal编程技术网

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之前,假设使用type
X
并提供
: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)
     }    
}