Swift从URLSession返回数据

时间:2017-03-27 13:42:41

标签: ios swift3 httprequest urlsession

我无法从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返回语句。在这一点上,我很无能......

4 个答案:

答案 0 :(得分:9)

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

For Instance: 我在完成块中返回了String,成功响应后没有错误只是将结果传递给块。

  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

        }

这将解决您的以下要求。

答案 1 :(得分: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作为参数,使用返回值执行任何操作,然后从完成处理程序中调用该方法。

答案 2 :(得分:1)

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

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

然后您应该使用类似return

的内容而不是completionHandler(data, response, error)

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

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()

答案 3 :(得分:1)

只是在你的函数调用中

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

你在字符串中有完整的回复,你可以返回