SpaceDog SpaceDog - 2 months ago 22
iOS Question

Synchronous URL request on Swift 2

I have this code from here to do synchronous request of a URL on Swift 2.

func send(url: String, f: (String)-> ()) {
var request = NSURLRequest(URL: NSURL(string: url)!)
var response: NSURLResponse?
var error: NSErrorPointer = nil
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: error)
var reply = NSString(data: data, encoding: NSUTF8StringEncoding)
f(reply)
}


but the function
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: error)
was deprecated and I don't see how one can do synchronous requests on Swift, cause the alternative is asynchronous. Apparently Apple deprecated the only function that can do it synchronously.

How can I do that?

Answer

There is a reason behind deprecation - there is just no use for it. You should avoid synchronous network requests as a plague. It has two main problems and only one advantage (it is easy to use.. but isn't async as well?):

  • The request blocks your UI if not called from different thread, but if you do that, why don't use asynchronous handler right away?
  • There is no way how to cancel that request except when it errors on its own

Instead of this, just use asynchronous request:

NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in

    // Handle incoming data like you would in synchronous request
    var reply = NSString(data: data, encoding: NSUTF8StringEncoding)
    f(reply)
})

iOS9 Deprecation

Since in iOS9 this method is being deprecated, I suggest you to use NSURLSession instead:

let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request) { (data, response, error) -> Void in

    // Handle incoming data like you would in synchronous request
    var reply = NSString(data: data, encoding: NSUTF8StringEncoding)
    f(reply)
}