Skip to content

Instantly share code, notes, and snippets.

@designatednerd
Created October 15, 2019 23:05
Show Gist options
  • Save designatednerd/93405c0751b0c62c3c575d687a409d45 to your computer and use it in GitHub Desktop.
Save designatednerd/93405c0751b0c62c3c575d687a409d45 to your computer and use it in GitHub Desktop.
Playground showing how to take an async API and make it synchronous
import UIKit
struct AsyncAPI {
enum AsyncAPIError: Error, LocalizedError {
case callDidNotCompleteSynchronously
case noErrorAndNoData
var errorDescription: String? {
switch self {
case .callDidNotCompleteSynchronously:
return "The synchrnous call did not complete within the given timeout!"
case .noErrorAndNoData:
return "A response was received but it contained neither data nor an error."
}
}
}
static func call(url: URL, completion: @escaping (Result<Data, Error>) -> Void) -> URLSessionTask {
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(error))
return
}
if let data = data {
completion(.success(data))
return
}
completion(.failure(AsyncAPIError.noErrorAndNoData))
}
task.resume()
return task
}
}
extension AsyncAPI {
static func callSynchronously(url: URL) -> Result<Data, Error> {
let semaphore = DispatchSemaphore(value: 0)
var functionResult: Result<Data, Error> = .failure(AsyncAPIError.callDidNotCompleteSynchronously)
self.call(url: url) { result in
functionResult = result
semaphore.signal()
}
semaphore.wait(timeout: .now() + 10)
return functionResult
}
}
let result = AsyncAPI.callSynchronously(url: URL(string: "http://httpbin.org/get")!)
switch result {
case .success(let data):
print("Success! Data:\n\(String(bytes: data, encoding: .utf8)!)")
case .failure(let error):
print("Fail! Error:\n\(error)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment