diff --git a/.changeset/ios-google-signin-presenting-window.md b/.changeset/ios-google-signin-presenting-window.md new file mode 100644 index 00000000000..b95ba824291 --- /dev/null +++ b/.changeset/ios-google-signin-presenting-window.md @@ -0,0 +1,5 @@ +--- +'@clerk/expo-google-signin': patch +--- + +Fix iOS Google sign-in failing with `GOOGLE_SIGN_IN_ERROR` in apps with more than one window or scene. The presenting view controller is now resolved from the key window of the foreground-active scene instead of an arbitrary window, so overlays such as splash screens or windows created by other modules no longer break the sign-in flow. diff --git a/packages/expo-google-signin/ios/ClerkGoogleSignInModule.swift b/packages/expo-google-signin/ios/ClerkGoogleSignInModule.swift index 5cc8fe13546..029bf31e0e0 100644 --- a/packages/expo-google-signin/ios/ClerkGoogleSignInModule.swift +++ b/packages/expo-google-signin/ios/ClerkGoogleSignInModule.swift @@ -143,14 +143,19 @@ public class ClerkGoogleSignInModule: Module { } private func getPresentingViewController() -> UIViewController? { - guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene, - let window = scene.windows.first, + let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene } + let scene = scenes.first { $0.activationState == .foregroundActive } + ?? scenes.first { $0.activationState == .foregroundInactive } + ?? scenes.first + + guard let window = scene?.windows.first(where: { $0.isKeyWindow && !$0.isHidden && $0.rootViewController != nil }) + ?? scene?.windows.first(where: { !$0.isHidden && $0.rootViewController != nil }), let rootVC = window.rootViewController else { return nil } var topVC = rootVC - while let presentedVC = topVC.presentedViewController { + while let presentedVC = topVC.presentedViewController, !presentedVC.isBeingDismissed { topVC = presentedVC } return topVC