【问题标题】:Swift return data from URLSession从 URLSession 快速返回数据
【发布时间】:2017-08-20 06:17:00
【问题描述】:

我无法从我的 HTTPrequest 返回数据,也无法让完成处理程序工作。所以请协助我解决这个问题:

public static func createRequest(qMes: message, location: String, method: String) -> String{
    let requestURL = URL(string: location)
    var request = URLRequest(url: requestURL!)

    request.httpMethod = method
    request.httpBody = qMes.toString().data(using: .utf8)

    let requestTask = URLSession.shared.dataTask(with: request) {
        (data: Data?, response: URLResponse?, error: Error?) in

        if(error != nil) {
            print("Error: \(error)")
        }

        return String(data: data!, encoding: String.Encoding.utf8) as String!
    }
    requestTask.resume()
}

在 void 函数中需要非 void return 语句。到这一步,我一头雾水……

【问题讨论】:

  • 您的return 语句位于dataTask(with:completionHandler:) 函数的完成块内;您的公共函数 createRequest 不返回任何内容,而它声称返回 String
  • 简单做:var webString = try String(contentsOf: URL(string: url)!)

标签: ios swift3 httprequest urlsession


【解决方案1】:

您可以使用此完成块方法发送最终响应:

例如: 我已经在完成块中返回了字符串,在成功响应无错误后,只需在块中传递结果。

  public func createRequest(qMes: String, location: String, method: String , completionBlock: @escaping (String) -> Void) -> Void
    {

        let requestURL = URL(string: location)
        var request = URLRequest(url: requestURL!)

        request.httpMethod = method
        request.httpBody = qMes.data(using: .utf8)

        let requestTask = URLSession.shared.dataTask(with: request) {
            (data: Data?, response: URLResponse?, error: Error?) in

            if(error != nil) {
                print("Error: \(error)")
            }else
            {

                let outputStr  = String(data: data!, encoding: String.Encoding.utf8) as String!
                //send this block to required place
                completionBlock(outputStr!);
            }
        }
        requestTask.resume()
    } 

您可以使用下面的代码来执行上面的完成块功能:

 self.createRequest(qMes: "", location: "", method: "") { (output) in

        }

这将解决您的以下要求。

【讨论】:

    【解决方案2】:
    {
        (data: Data?, response: URLResponse?, error: Error?) in
    
        if(error != nil) {
            print("Error: \(error)")
        }
    
        return String(data: data!, encoding: String.Encoding.utf8) as String!
    }
    

    这部分代码是dataTask() 方法的完成处理程序。这是您传递给dataTask() 方法的代码块,以便稍后执行(当服务器发回一些数据或出现错误时)。它不会立即执行。

    这意味着当上面的createRequest() 方法正在执行时,它会直接传递该代码,然后传递到requestTask.resume() 行,然后方法结束。此时,因为您的方法被定义为返回一个String,所以您需要返回一个String。从完成处理程序中返回它是不好的,因为它还没有执行,稍后会执行。

    处理异步编程有很多不同的方法,但解决此问题的一种方法是更改​​您的 createRequest() 方法,使其未定义为返回 String,创建一个采用 String 的方法作为一个参数,它可以对返回值做任何你想做的事情,然后从你的完成处理程序中调用该方法。

    【讨论】:

    • 感谢您提供的额外信息,在理解这一点时遇到了一些麻烦!太好了!
    【解决方案3】:

    不要使用 return,而是尝试使用您在问题中提到的完成处理程序。

    func createRequest(qMes: message, location: String, method: String, completionHandler: @escaping (_ data:Data?, _ response: URLResponse?, _ error: NSError?) -> Void)
    

    那么你应该使用 completionHandler(data, response, error) 之类的东西,而不是 return

    这就是你提出请求的方式:

    var request = URLRequest(url: Foundation.URL(string: URL)!)
            request.httpMethod = method
            //request.addValue(authString, forHTTPHeaderField: "Authorization") // if you need some
    
            let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
    
                guard error == nil && data != nil else
                {
                    print("error=\(error)")
                    completionHandler(data, response, error as NSError?)
                    return
                }
    
                completionHandler(data, response, error as NSError?)
            }) 
    
            task.resume()
    

    【讨论】:

      【解决方案4】:

      就在你的函数调用中

      var webString = try String(contentsOf: URL(string: url)!)
      

      你有完整的字符串响应,你可以返回

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多