Xcode13で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