Xcode 13 で Swift に async/await が追加され、既存のプロジェクトを async/await 対応する機会があると思います。 その上で、Closure で書かれている処理を async/await 対応する必要があったのでその方法をメモしておきます。
今回は Firebase の TwitterAuth で使用する getCredentialWith が async/await 対応されていなかったので、自前で対応しようと思います。 参考:iOS で Twitter を使用して認証する
元の Closure 関数
twitter の Provider を指定して、Credential 情報を取得する Closure 関数です。
let twitterProvider = OAuthProvider(providerID: "twitter.com")
func getTwitterCredential(completion: ((Result<AuthCredential, Error>) -> Void)? = nil) {
twitterProvider.getCredentialWith(nil) { credential, error in
if let error = error {
log.error("Twitter Auth error: \(error)")
completion?(.failure(error))
}
completion?(.success(credential))
}
}
async / await 化する
Closure を async/await 化するには withCheckedThrowingContinuation または、withCheckedContinuation 関数を使用します。
今回はエラーを throw するので、withCheckedThrowingContinuation を使用して Closure 関数をラップします。 処理が終了したら CheckedContinuation の resume() を呼んでそれらを返します。
func getTwitterCredential() async throws -> AuthCredential {
return try await withCheckedThrowingContinuation { continuation in
twitterProvider.getCredentialWith(nil) { credential, error in
if let error = error {
log.error("Twitter Auth error: \(error)")
continuation.resume(throwing: error)
} else if let credential = credential {
continuation.resume(returning: credential)
}
}
}
}
作成した async 関数を呼び出す
do {
let credential = try await self.getTwitterCredential()
} catch {
log.error(error)
}
参考
https://zenn.dev/treastrain/articles/484564cf15a8a1 https://zenn.dev/treastrain/articles/e8099976ec845b https://developer.apple.com/videos/play/wwdc2021/10132/ https://developer.apple.com/documentation/swift/3814988-withcheckedcontinuation https://developer.apple.com/documentation/swift/3814989-withcheckedthrowingcontinuation