Skip to content

Instantly share code, notes, and snippets.

@dennislysenko
Created March 27, 2018 19:03
Show Gist options
  • Save dennislysenko/f5de6d6ab818e4e85eb69fd118c9d256 to your computer and use it in GitHub Desktop.
Save dennislysenko/f5de6d6ab818e4e85eb69fd118c9d256 to your computer and use it in GitHub Desktop.
Convenience methods for sync-to-async conversion in Swift with a Result<T> monad that represents a failable result.
// call like: asyncify(runRequest)(arg) { success in ... }
func asyncify<P, R>(_ function: @escaping (P) throws -> (R)) -> ((P, _ completion: @escaping ((Result<R>) -> Void)) -> Void) {
return { (arg: P, completion: @escaping (Result<R>) -> Void) in
DispatchQueue.global(qos: .background).async {
do {
let result = try function(arg)
DispatchQueue.main.async {
completion(.success(result))
}
} catch let error {
DispatchQueue.main.async {
completion(.failure(error))
}
}
}
}
}
// call like: asyncify(simpleOperation) { success in ... }
func asyncify<R>(_ function: @escaping () throws -> (R), _ completion: @escaping ((Result<R>) -> Void)) {
DispatchQueue.global(qos: .background).async {
do {
let result = try function()
DispatchQueue.main.async {
completion(.success(result))
}
} catch let error {
DispatchQueue.main.async {
completion(.failure(error))
}
}
}
}
public enum Result<T>: CustomStringConvertible {
case success(T)
case failure(Error)
public var description: String {
switch self {
case .success(let value):
return "Success(\(value))"
case .failure(let error):
return "Failure(\(String(reflecting: error)))"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment