如何使用 SwiftUI 2.0 架构设置 Firebase Google SignIn 6.0.2?
How to set up Firebase Google SignIn 6.0.2 using SwiftUI 2.0 architecture?
我正在尝试使用 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 但没有代码示例说明如何正确执行此操作。
您可能希望 运行 该代码作为用户执行操作的结果。例如按下 Button
之后。
棘手的部分将是 GIDSignIn.sharedInstance.signIn
需要一个 UIViewController
作为它的 presenting
参数,这在 SwiftUI 中不一定是直接获得的。您可以使用 UIViewControllerRepresentable
来获取对层次结构中可以呈现的视图控制器的引用。
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)
}
}
}
}
我正在尝试使用 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 但没有代码示例说明如何正确执行此操作。
您可能希望 运行 该代码作为用户执行操作的结果。例如按下 Button
之后。
棘手的部分将是 GIDSignIn.sharedInstance.signIn
需要一个 UIViewController
作为它的 presenting
参数,这在 SwiftUI 中不一定是直接获得的。您可以使用 UIViewControllerRepresentable
来获取对层次结构中可以呈现的视图控制器的引用。
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)
}
}
}
}