Swift return data from URLSession

风格不统一 提交于 2019-12-20 19:42:49

问题


I cannot return data from my HTTPrequest and I can't get completion handlers to work either. 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. At this point I'm clueless...


回答1:


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.

  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.




回答2:


{
    (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. 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). 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. At that point, because your method is defined as returning a String, you need to return a 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.




回答3:


Instead of using return, try using completion handlers as you mentioned in your question.

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)

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



回答4:


Just in your function call

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

And you have full response in string, that you can return



来源:https://stackoverflow.com/questions/43048120/swift-return-data-from-urlsession

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!