首页 > 解决方案 > 如何使用 SwiftUI 2.0 架构设置 Firebase Google SignIn 6.0.2?

问题描述

我正在尝试使用 SwiftUI 设置最新的 GoogleSignIn。Firebase 官方文档提供了为 UIKit、ViewControllers 和 AppDelegate 设计的过时方法,因此根本无法找出需要什么解决方法才能使其正常工作。我能够实现 UIApplicationDelegateAdaptor 来访问 didFinishLaunchingWithOptions 方法来配置 FirebaseApp 和 GIDSignIn。在遵循此文档时:https ://firebase.google.com/docs/auth/ios/google-signin我最终坚持第 4 步。目前尚不清楚我必须在哪里使用此代码或如何将其集成到 SwiftUI 范例中:

guard let clientID = FirebaseApp.app()?.options.clientID else { return }

// Create Google Sign In configuration object.
let config = GIDConfiguration(clientID: clientID)

// Start the sign in flow!
GIDSignIn.sharedInstance.signIn(with: config, presenting: self) { [unowned self] user, error in

  if let error = error {
    // ...
    return
  }

  guard
    let authentication = user?.authentication,
    let idToken = authentication.idToken
  else {
    return
  }

  let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                 accessToken: authentication.accessToken)

  // ...
}

我知道来自 Google 的这份指南:https ://developers.google.com/identity/sign-in/ios/quick-migration-guide但没有代码示例说明如何正确执行此操作。

标签: swiftfirebaseswiftuigoogle-signin

解决方案


您可能希望根据用户执行的操作来运行该代码。Button例如,按下 a 后。

棘手的部分将是它的论点需要GIDSignIn.sharedInstance.signIn一个,这在 SwiftUI 中并不一定很简单。您可以使用 a来获取对层次结构中可以呈现的视图控制器的引用。UIViewControllerpresentingUIViewControllerRepresentable

class LoginManager : ObservableObject {
    var viewController : UIViewController?
    
    func runLogin() {
        guard let viewController = viewController else {
            fatalError("No view controller")
        }
        
        //Other GIDSignIn code here. Use viewController for the `presenting` argument
    }
}

struct DummyViewController : UIViewControllerRepresentable {
    var loginManager : LoginManager
    
    func makeUIViewController(context: Context) -> some UIViewController {
        let vc = UIViewController()
        loginManager.viewController = vc
        return vc
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        
    }
}

struct ContentView : View {
    @StateObject private var loginManager = LoginManager()
    
    var body: some View {
        VStack(spacing: 0) {
            Button(action: {
                loginManager.runLogin()
            }) {
                Text("Login")
                DummyViewController(loginManager: loginManager)
                    .frame(width: 0, height: 0)
            }
        }
    }
}

推荐阅读