It might sound stupid(and most of the time it is) but there are situations when you want to make a synchronous request using URLSession. I faced the situation when I had to log both request and response together.
Semaphores and Synchronous HTTP request
A asynchronous request looks something like this
func myRequest(){ var request = URLRequest(url: URL(string: "your URL")!); request.httpMethod = "GET" let task = URLSession.shared.dataTask(with: request) { (data, response, error) in //get responce here } task.resume() }
To make it behave we need to add semaphores. Semaphores are a signal person of multithreading world. They keep one side of traffic paused till the other side has completed its operation. Semaphores will work for us in two steps
- Pause calling thread till Data task is ongoing
- Give signal that data task is over now our calling thread can resume
Semaphore adaptation of our example above is given below
import UIKit import Foundation func myRequest(){ var request = URLRequest(url: URL(string: "your URL")!); request.httpMethod = "GET" let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0) let task = URLSession.shared.dataTask(with: request) { (data, response, error) in //get responce here //Use response print("2") semaphore.signal() } task.resume() print("1") semaphore.wait() print("3") }
Caution while using semaphores
Semaphore use can make the calling thread pause. It won’t be very bright if we start using the above-given approach on the main thread. You will need to dispatch your calls as shown below at least.
DispatchQueue.global().async { myRequest() }
Hope this helps someone in search of the synchronous HTTP request and is getting schooled about not using them instead of getting the solution.