Hamzah Malik
Hamzah Malik

Reputation: 2570

Swift - Return data from NSURLSession when sending POST request

I can send a POST request in Swift using the below code

func post() -> String{
    let request = NSMutableURLRequest(URL: NSURL(string: "http://myserverip/myfile.php")!)
    request.HTTPMethod = "POST"
    let postString = "data=xxxxxxx"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in
        if error != nil {
            println("error=\(error)")
            return
        }

        println("response = \(response)")

        let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("responseString = \(responseString!)")

    }
    task.resume()



    return "";//how would i return data here
}

I need to return the result, but this isn't possible since the network request is asynchronous. I think I can use a listener to wait for the result and then return it, but I'm not sure how this would work or how to implement it If anyone could help, I would greatly appreciate it I am new to both iOS and Swift

Upvotes: 4

Views: 4538

Answers (2)

GaétanZ
GaétanZ

Reputation: 4930

You can use a delegate or pass a function as an argument of post that you call at the end

Example with a completion handler :

 struct RemoteCenter {
    static func post(completion: (message: String?) -> Void) {
        let request = NSMutableURLRequest(URL: NSURL(string: "http://myserverip/myfile.php")!)
        request.HTTPMethod = "POST"

        let postString = "data=xxxxxxx"
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in
            if error != nil {
                println("error=\(error)")
                return
            }

            completion(message: NSString(data: data, encoding: NSUTF8StringEncoding) as? String)
        }

        task.resume()
    }
}

class YourController: UIViewController {
    override func viewDidLoad() {
        RemoteCenter.post(completionHandler)
    }

    func completionHandler(message: String?){
        println("I got \(message)")
    }
}

Example with a delegate :

protocol DelegateProtocol {
    func didReceiveAMessage(message: String?)
}

struct RemoteCenter {
    var delegate:DelegateProtocol?

    func post() {
        let request = NSMutableURLRequest(URL: NSURL(string: "http://myserverip/myfile.php")!)
        request.HTTPMethod = "POST"

        let postString = "data=xxxxxxx"
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in
            if error != nil {
                println("error=\(error)")
                return
            }

            self.delegate?.didReceiveAMessage(NSString(data: data, encoding: NSUTF8StringEncoding) as? String)
        }

        task.resume()
    }
}

class YourController: UIViewController, DelegateProtocol {

    var remote = RemoteCenter()

    override func viewDidLoad() {
        remote.delegate = self
        remote.post()
    }

    func didReceiveAMessage(message: String?) {
        println("I got \(message)")
    }
}

In both cases, the goal is to fetch some data on the internet from an UIViewController and print the message when it's done.

You can find so many tutorials about it. Check http://www.raywenderlich.com

Upvotes: 2

enes
enes

Reputation: 329

Your post function might be like:

func post(completionHandler: (response: String) -> ()) { your code }

And in the response part:

let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
completionHandler(response: responseString)

Finally, you can call your post method like:

post( {(response: String) -> () in
               println("response = \(response)")})

Upvotes: 4

Related Questions