Оберните звонки в обещания. Любая из популярных библиотек сделает свое дело. На ум приходит PromiseKit, доступный (на момент написания этой статьи) по номеру https://github.com/mxcl/PromiseKit.
Вот код, который я написал для рабочего проекта (он с открытым исходным кодом), который оборачивает функцию, которая принимает завершение, и возвращает Promise, который будет сигнализировать с результатом, когда вызывается завершение. Он использует внутреннюю реализацию Promise, но этот процесс можно адаптировать к другим реализациям.
public func promise<Return>(_ task: (@escaping (Return?, Error?) -> ()) -> ()) -> Promise<Return> {
let p = Promise<Return>()
task { (value: Return?, error: Error?) -> Void in
if let error = error {
p.signal(error)
}
if let value = value {
p.signal(value)
}
}
return p
}
Ожидается, что завершение будет вызвано каким-либо результатом или ошибкой. Адаптируйте, как требуется для вашего варианта использования.
Ниже приведен пример использования.
public typealias BalanceCompletion = (Balance?, Error?) -> Void
func balance(completion: @escaping BalanceCompletion) {
guard deleted == false else {
completion(nil, KinError.accountDeleted)
return
}
Stellar.balance(account: stellarAccount.publicKey!, asset: asset, node: node)
.then { balance -> Void in
completion(balance, nil)
}
.error { error in
completion(nil, KinError.balanceQueryFailed(error))
}
}
func balance() -> Promise<Balance> {
return promise(balance)
}