简体   繁体   English

从URLSession快速返回数据

[英]Swift return data from URLSession

I cannot return data from my HTTPrequest and I can't get completion handlers to work either. 我无法从HTTPrequest返回数据,也无法使完成处理程序正常工作。 So please assist me in my quest to solve this issue: 因此,请协助我解决这个问题:

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

It is excpecting non-void return statement in void function. 期待void函数中的非void return语句。 At this point I'm clueless... 在这一点上我一无所知...

You can use this completion block method to send the final response: 您可以使用此完成块方法发送最终响应:

For Instance: I have returned String in completion block, after successful response without error just pass the result in block. 对于实例:我在完成块中返回了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()
    } 

You can use this below code to execute the above completion block function: 您可以使用以下代码执行上述完成块功能:

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

        }

This will solve your following requirement. 这将解决您的以下要求。

{
    (data: Data?, response: URLResponse?, error: Error?) in

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

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

This part of your code is the completion handler for the dataTask() method. 您的代码的这一部分是dataTask()方法的完成处理程序。 It's a block of code that you pass into the dataTask() method to be executed later on (when the server sends back some data or there's an error). 这是一段代码,您将传递给dataTask()方法,以便稍后执行(当服务器发回一些数据或发生错误时)。 It's not executed straight away. 它不会立即执行。

This means that when your createRequest() method above is executing, it passes straight over that code, then onto the requestTask.resume() line, and then the method ends. 这意味着当您执行上面的createRequest()方法时,它将直接越过该代码,然后传递到requestTask.resume()行,然后该方法结束。 At that point, because your method is defined as returning a String , you need to return a String . 那时,由于您的方法定义为返回String ,因此您需要返回String Returning it from the completion handler is no good because that hasn't been executed yet, that is going to be executed later on. 从完成处理程序返回它是不好的,因为还没有执行,将在以后执行。

There's lots of different ways to handle asynchronous programming, but one way of tackling this is to change your createRequest() method so that it isn't defined to return a String , create a method that takes a String as a parameter which does whatever you wanted to do with the return value, and then call that method from your completion handler. 处理异步编程的方法有很多,但是解决该问题的一种方法是更改​​您的createRequest()方法,以便不定义它返回String ,创建一个将String作为参数的方法,该方法可以完成您的所有操作想要处理返回值,然后从完成处理程序中调用该方法。

Instead of using return, try using completion handlers as you mentioned in your question. 而不是使用return,请尝试使用问题中提到的完成处理程序。

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

Then instead of return you should use something like completionHandler(data, response, error) 然后,而不是return您应该使用诸如completionHandler(data, response, error)

And this is how you make the request: 这是您发出请求的方式:

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

Just in your function call 就在您的函数调用中

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

And you have full response in string, that you can return 而且您对字符串有完整的响应,可以返回

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM