Skip to content

Instantly share code, notes, and snippets.

@algal
Last active April 25, 2017 03:20
Show Gist options
  • Save algal/8a8fbb20ca1c18e840ac49b1fcbc66e6 to your computer and use it in GitHub Desktop.
Save algal/8a8fbb20ca1c18e840ac49b1fcbc66e6 to your computer and use it in GitHub Desktop.
Synchronous HTTP request in
// known-good: 8.3.2, Swift 3
/**
Sometimes you just want to launch a synchronous HTTP request for some JSON, damnit.
Other approaches here: https://github.com/algal/SynchronousDownloadPlayground
*/
extension URLSession {
func sendSynchronousRequest(_ request:URLRequest,
timeout:TimeInterval = -1) -> (Data?,URLResponse?,NSError?)?
{
let sem = DispatchSemaphore(value: 0)
var result:(Data?,URLResponse?,NSError?)
let task = self.dataTask(with: request, completionHandler: { (theData, theResponse, theError) in
result = (theData,theResponse,theError as NSError?)
sem.signal()
})
task.resume()
let t = timeout == -1 ? DispatchTime.distantFuture : DispatchTime.now() + Double(Int64(NSEC_PER_SEC) * Int64(timeout)) / Double(NSEC_PER_SEC)
let noTimeout = sem.wait(timeout: t)
if noTimeout == .timedOut {
return nil
}
return result
}
/// Synchronously launches a URL request, returning JSON or nil on timeout
func sendSynchronousRequest(_ request:URLRequest,
timeout:TimeInterval = -1) -> [String:Any]?
{
guard
let result:(Data?,URLResponse?,NSError?) = sendSynchronousRequest(request,timeout:timeout),
let data = result.0,
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
let jsonDict = jsonObject as? [String:Any]
else { return nil }
return jsonDict
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment