GoogleSignIn 6.2.4 has the signIn operate that requires a presenting UIViewController.
To unravel this, add a sceneDelegate to the setting so it is accessible to SwiftUI.
Arrange an AppDelegate so we are able to hook up our SceneDelegate
class AppDelegate: NSObject, UIApplicationDelegate {
// Hook up our SceneDelegate
func software(_ software: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
choices: UIScene.ConnectionOptions) -> UISceneConfiguration {
let configuration = UISceneConfiguration(title: nil, sessionRole: connectingSceneSession.function)
if connectingSceneSession.function == .windowApplication {
configuration.delegateClass = SceneDelegate.self
}
return configuration
}
}
Arrange a SceneDelegate as an ObservableObject to maintain monitor of the window
// Set this up so we are able to entry the window within the setting
class SceneDelegate: NSObject, ObservableObject, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, choices connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
self.window = windowScene.keyWindow
}
}
Be sure you allow the AppDelegate within the App
@primary
struct AdrichApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var physique: some Scene {
WindowGroup {
ContentView()
}
}
}
Lastly, use it in a SwiftUI View to point out your Proceed with Google button
struct SignInWithGoogle: View {
@EnvironmentObject var sceneDelegate: SceneDelegate
var physique: some View {
if let vc = sceneDelegate.window?.rootViewController {
continueWithGoogle(config: GIDConfiguration(clientID: "YOUR CLINET ID"), presenter: vc)
} else {
emptyView
}
}
personal var emptyView: some View {
print("Unable to entry the foundation view controller")
return EmptyView()
}
personal func continueWithGoogle(config: GIDConfiguration, presenter: UIViewController) -> some View {
Button {
GIDSignIn.sharedInstance.signIn(with: config, presenting: presenter) { person, error in
if let error = error {
print(error)
return
}
guard
let authentication = person?.authentication,
let idToken = authentication.idToken
else {
return
}
let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
// they're now signed in with Google!
}
} label: {
Textual content("Proceed with Google")
}
}
}