1

I call some function in another thread:

dispatch_async(dispatch_get_global_queue(priority, 0)) {
     self.someFunction()
}

Then in this function i want do synchronous request:

let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let dataSemaphore = dispatch_semaphore_create(0)

let task = session.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) in
guard let responseData = data else {
    print("Error: did not receive data")
    return
}
guard error == nil else {
    print("error calling GET")
    print(error)
    return
    }
    print("ASYNC")
})
task.resume()

dispatch_semaphore_wait(dataSemaphore, DISPATCH_TIME_FOREVER)

print("SYNC")

But thread stops dispatch_semaphore_wait(dataSemaphore, DISPATCH_TIME_FOREVER) at this line

Arti
  • 7,356
  • 12
  • 57
  • 122

2 Answers2

1

You never signaled the semaphore, put this at the end of your completion handler:

dispatch_semaphore_signal(dataSemaphore)
Kametrixom
  • 14,673
  • 7
  • 45
  • 62
  • thanks, and can you help, how to set timeoutInterval to this function ? If we don't have response in 30 seconds for example, continiue – Arti Nov 17 '15 at 13:01
  • 1
    @Arti Just replace `DISPATCH_TIME_FOREVER` with `dispatch_time(DISPATCH_TIME_NOW, Int64(numberOfSeconds * Double(NSEC_PER_SEC)))` – Kametrixom Nov 17 '15 at 13:05
0

Although the other answer here is technically correct, I feel the need to post a second answer, asking why you're doing this....

Synchronous networking is almost never the right way to do anything. Instead, you really should make the rest of the function be a block that gets run when the request finishes.

The fact that it is technically possible to create a synchronous wrapper for an async API doesn't negate the fact that doing so blocks whatever thread is running this code, so unless you're in a situation where you need to enforce some sort of strict ordering over network requests, synchronous requests are generally a bad idea, and even then, they aren't a good idea.

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • I should make N requests. They call each other after finish. So i did this like: I call one function asynchronous, and all other requests in this function make synchronous. – Arti Dec 04 '15 at 10:45