Skip to content

Instantly share code, notes, and snippets.

@Krelborn
Created May 23, 2015 10:46
Show Gist options
  • Save Krelborn/3cade0e86cc9f06637b6 to your computer and use it in GitHub Desktop.
Save Krelborn/3cade0e86cc9f06637b6 to your computer and use it in GitHub Desktop.
Simple way to perform an asynchronous closure synchronously. Useful for unit testing synchronous calls like NSURLSession etc.
/**
* Simple way to perform an asynchronous closure synchronously
*
* Simply use the **run** method to execute the given closure that executes something with an
* asynchronous closure and signal when its complete.
*
* Sync.run { sync in somethingWithAsyncCallback { sync.signal() } }
*/
public struct Sync {
private var semaphore: dispatch_semaphore_t
init() {
semaphore = dispatch_semaphore_create(0)
}
/**
Waits until we are signalled
:param: timeoutSeconds Maximum time in seconds. Passing a value of 0.0 will wait forever.
*/
public func wait(timeoutSeconds: Double = 0.0) {
let timeout: dispatch_time_t
if timeoutSeconds != 0.0 {
timeout = dispatch_time(DISPATCH_TIME_NOW, Int64(timeoutSeconds * Double(NSEC_PER_SEC)))
} else {
timeout = DISPATCH_TIME_FOREVER
}
dispatch_semaphore_wait(semaphore, timeout)
}
/**
Signal to wakeup waiters
*/
public func signal() {
dispatch_semaphore_signal(semaphore)
}
/**
Convenience method that will execute the given closure and wait for completion. The Sync must
be signalled from inside the closure.
:param: closure Function to execute synchronously
*/
public func run(closure: (Sync) -> ()) {
closure(self)
wait()
}
/**
Convenience static method that will execute the given closure and wait for completion.
:param: closure Function to execute synchronously
*/
public static func run(closure: (Sync) -> ()) {
var sync = Sync()
sync.run(closure)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment