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 関数をラップします。 処理が終了したら CheckedContinuationresume() を呼んでそれらを返します。

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