AuthDefaultUIDelegate.swift 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright 2023 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. #if os(iOS) || os(tvOS)
  15. import Foundation
  16. import UIKit
  17. /** @class AuthDefaultUIDelegate
  18. @brief Class responsible for providing a default FIRAuthUIDelegate.
  19. @remarks This class should be used in the case that a UIDelegate was expected and necessary to
  20. continue a given flow, but none was provided.
  21. */
  22. class AuthDefaultUIDelegate: NSObject, AuthUIDelegate {
  23. // TODO: Figure out what to do for extensions.
  24. /** @fn defaultUIDelegate
  25. @brief Returns a default FIRAuthUIDelegate object.
  26. @return The default FIRAuthUIDelegate object.
  27. */
  28. @available(iOSApplicationExtension, unavailable)
  29. @available(tvOSApplicationExtension, unavailable)
  30. class func defaultUIDelegate() -> AuthUIDelegate? {
  31. // TODO: Consider removing code below when doing extension testing.
  32. // iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication
  33. // responds to it.
  34. guard let applicationClass = NSClassFromString("UIApplication"),
  35. applicationClass.responds(to: NSSelectorFromString("sharedApplication")) else {
  36. return nil
  37. }
  38. var topViewController: UIViewController?
  39. if #available(iOS 13.0, tvOS 13.0, *) {
  40. let connectedScenes = UIApplication.shared.connectedScenes
  41. for scene in connectedScenes {
  42. if let windowScene = scene as? UIWindowScene {
  43. for window in windowScene.windows {
  44. if window.isKeyWindow {
  45. topViewController = window.rootViewController
  46. }
  47. }
  48. }
  49. }
  50. } else {
  51. topViewController = UIApplication.shared.keyWindow?.rootViewController
  52. }
  53. while true {
  54. if let controller = topViewController?.presentedViewController {
  55. topViewController = controller
  56. } else if let navController = topViewController as? UINavigationController {
  57. topViewController = navController.topViewController
  58. } else if let tabBarController = topViewController as? UITabBarController {
  59. topViewController = tabBarController.selectedViewController
  60. } else {
  61. break
  62. }
  63. }
  64. return AuthDefaultUIDelegate(withViewController: topViewController)
  65. }
  66. init(withViewController viewController: UIViewController?) {
  67. self.viewController = viewController
  68. }
  69. func present(_ viewControllerToPresent: UIViewController, animated flag: Bool,
  70. completion: (() -> Void)? = nil) {
  71. viewController?.present(viewControllerToPresent, animated: flag, completion: completion)
  72. }
  73. func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
  74. viewController?.dismiss(animated: flag, completion: completion)
  75. }
  76. private let viewController: UIViewController?
  77. }
  78. #endif