通用可解码协议Swift 4.2解开可选错误

时间:2018-06-24 13:15:07

标签: ios iphone swift

此处的通用可解码协议存在问题,似乎它返回了可选的展开错误。我是Swift的新手,但我不知道为什么它返回可选的。请参阅下面的代码:

public func requestGenericData<T: Decodable>(urlString: String, httpMethod: String, token: String) -> T? {
    var result: T?
    let fullStringUrl: String = self.url + urlString
    let urlReq = URL(string: fullStringUrl)
    var urlRequest = URLRequest(url: urlReq!)
    urlRequest.setValue("application/json", forHTTPHeaderField: "accept")
    urlRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    urlRequest.httpMethod = httpMethod
    URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
        if self.isInternetAvailable() {
            guard let data = data else { return }
            if let httpResponse = response as? HTTPURLResponse {
                if httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 {
                    do {
                        let parsedObj = try JSONDecoder().decode(T.self, from: data)
                        result = parsedObj
                    } catch {
                        print("Error: \(String(describing: error))\n StatusCode: \(httpResponse.statusCode)")
                    }
                }
            }
        } else {
            showAlert(title: "No Internet Connect", message: "Please open your network and try again.", alertStyle: .alert, buttonTitle: "OK", buttonStyle: .default)
            return
        }
    }.resume()

    return result
}

更新:错误

  

线程1:致命错误:在展开可选值时意外发现nil

2 个答案:

答案 0 :(得分:0)

URLSession.dataTask(with:completionHandler:)是一种异步方法。您的requestGenericData函数在 URLSession.dataTask之前返回了。因此,当result返回时,您的nil变量仍为requestGenericData

您还需要使函数异步。它应该将完成处理程序作为参数,然后从URLSession.dataTask的完成处理程序中调用它。

答案 1 :(得分:0)

您可以对此进行更新,检查return是否为true / false,然后使用返回的值

public func requestGenericData<T: Decodable>(urlString: String, httpMethod: String, token: String,completion:@escaping(_ result:T?,_ success:Bool)-> Void) {

    let fullStringUrl: String = self.url + urlString
    let urlReq = URL(string: fullStringUrl)
    var urlRequest = URLRequest(url: urlReq!)
    urlRequest.setValue("application/json", forHTTPHeaderField: "accept")
    urlRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    urlRequest.httpMethod = httpMethod
    URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
        if self.isInternetAvailable() {
            guard let data = data else { return }
            if let httpResponse = response as? HTTPURLResponse {
                if httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 {
                    do {
                        let parsedObj = try JSONDecoder().decode(T.self, from: data)
                        completion(parsedObj,true)
                    } catch {
                        print("Error: \(String(describing: error))\n StatusCode: \(httpResponse.statusCode)")
                         completion(nil,false)
                    }
                }
            }
        } else {
            showAlert(title: "No Internet Connect", message: "Please open your network and try again.", alertStyle: .alert, buttonTitle: "OK", buttonStyle: .default)
             completion(nil,false)
        }
    }.resume()


}

//

称呼它

requestGenericData(urlString:<#url#>,httpMethod:<#httpMethod#>,token:<#token#>) { (result,success) in 

  if success {

  }
}