PhoneAuthViewController.swift 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import FirebaseAuth
  15. import UIKit
  16. class PhoneAuthViewController: OtherAuthViewController {
  17. override func viewDidLoad() {
  18. super.viewDidLoad()
  19. configureUI(for: .PhoneNumber)
  20. }
  21. override func buttonTapped() {
  22. guard let phoneNumber = textField.text, !phoneNumber.isEmpty else { return }
  23. phoneAuthLogin(phoneNumber)
  24. }
  25. // MARK: - Firebase 🔥
  26. private func phoneAuthLogin(_ phoneNumber: String) {
  27. let phoneNumber = String(format: "+%@", phoneNumber)
  28. Task {
  29. do {
  30. let phoneAuthProvider = PhoneAuthProvider.provider()
  31. let verificationID = try await phoneAuthProvider.verifyPhoneNumber(phoneNumber)
  32. let verificationCode = try await getVerificationCode()
  33. let credential = phoneAuthProvider.credential(withVerificationID: verificationID,
  34. verificationCode: verificationCode)
  35. self.signin(with: credential)
  36. } catch {
  37. self.displayError(error)
  38. }
  39. }
  40. }
  41. private func signin(with credential: PhoneAuthCredential) {
  42. AppManager.shared.auth().signIn(with: credential) { result, error in
  43. guard error == nil else { return self.displayError(error) }
  44. self.navigationController?.dismiss(animated: true, completion: {
  45. self.delegate?.loginDidOccur()
  46. })
  47. }
  48. }
  49. private func presentPhoneAuthController(saveHandler: @escaping (String) -> Void) {
  50. let phoneAuthController = UIAlertController(
  51. title: "Sign in with Phone Auth",
  52. message: nil,
  53. preferredStyle: .alert
  54. )
  55. phoneAuthController.addTextField { textfield in
  56. textfield.placeholder = "Enter verification code."
  57. textfield.textContentType = .oneTimeCode
  58. }
  59. let onContinue: (UIAlertAction) -> Void = { _ in
  60. let text = phoneAuthController.textFields!.first!.text!
  61. saveHandler(text)
  62. }
  63. phoneAuthController
  64. .addAction(UIAlertAction(title: "Continue", style: .default, handler: onContinue))
  65. phoneAuthController.addAction(UIAlertAction(title: "Cancel", style: .cancel))
  66. present(phoneAuthController, animated: true, completion: nil)
  67. }
  68. private func getVerificationCode() async throws -> String {
  69. return try await withCheckedThrowingContinuation { continuation in
  70. self.presentPhoneAuthController { code in
  71. if code != "" {
  72. continuation.resume(returning: code)
  73. } else {
  74. // Cancelled
  75. continuation.resume(throwing: NSError())
  76. }
  77. }
  78. }
  79. }
  80. }