From 96ecdc924134ee5a8852721c0a1e0aaf934f8a2b Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 21 Jul 2025 10:44:49 -0400 Subject: [PATCH 1/2] [google_sign_in] Update to GoogleSignIn-iOS 9 Updates the dependency on the GoogleSignIn iOS SDK to the recently released 9.0. Some specific benefits include: - Allows wiring up the nonce parameter on iOS, which was plumbed most of the way through already since the PR had landed upstream when nonce was added to `google_sign_in`, but not fully connected since it wasn't released. - Avoids transitive dependency conflicts with plugins that use AppAuth 2.x. Fixes https://github.com/flutter/flutter/issues/172453 Finishes https://github.com/flutter/flutter/issues/85439 for iOS --- .../google_sign_in_ios/CHANGELOG.md | 5 +++ .../darwin/Tests/GoogleSignInTests.m | 41 +++++++++++++++++++ .../darwin/google_sign_in_ios.podspec | 7 ++-- .../darwin/google_sign_in_ios/Package.swift | 2 +- .../FLTGoogleSignInPlugin.m | 5 +-- .../google_sign_in_ios/pubspec.yaml | 2 +- 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md b/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md index fa290a057d8..20e2e987c4f 100644 --- a/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.1.0 + +* Updates to `GoogleSignIn` 9.0. +* Adds support for the `nonce` parameter. + ## 6.0.1 * Returns configuration errors as `PlatformException`s in Dart instead of diff --git a/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m b/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m index d80c161d1c4..34ef4472e40 100644 --- a/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m +++ b/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m @@ -263,6 +263,7 @@ - (void)testSignIn { [self configureMock:[self.mockSignIn expect] forSignInWithHint:nil additionalScopes:@[] + nonce:nil completion:[OCMArg invokeBlockWithArgs:mockSignInResult, [NSNull null], nil]]; XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"]; @@ -302,6 +303,7 @@ - (void)testSignInWithScopeHint { additionalScopes:[OCMArg checkWithBlock:^BOOL(NSArray *scopes) { return [[NSSet setWithArray:scopes] isEqualToSet:[NSSet setWithArray:requestedScopes]]; }] + nonce:nil completion:[OCMArg invokeBlockWithArgs:mockSignInResult, [NSNull null], nil]]; XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"]; @@ -318,6 +320,39 @@ - (void)testSignInWithScopeHint { OCMVerifyAll(self.mockSignIn); } +- (void)testSignInWithNonce { + FlutterError *initializationError; + [self.plugin configureWithParameters:[FSIPlatformConfigurationParams makeWithClientId:nil + serverClientId:nil + hostedDomain:nil] + error:&initializationError]; + + id mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([mockUser userID]).andReturn(@"mockID"); + id mockSignInResult = OCMClassMock([GIDSignInResult class]); + OCMStub([mockSignInResult user]).andReturn(mockUser); + + NSString *nonce = @"A nonce"; + [self configureMock:[self.mockSignIn expect] + forSignInWithHint:nil + additionalScopes:OCMOCK_ANY + nonce:nonce + completion:[OCMArg invokeBlockWithArgs:mockSignInResult, [NSNull null], nil]]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"]; + [self.plugin signInWithScopeHint:@[] + nonce:nonce + completion:^(FSISignInResult *result, FlutterError *error) { + XCTAssertNil(error); + XCTAssertNil(result.error); + XCTAssertEqualObjects(result.success.user.userId, @"mockID"); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + + OCMVerifyAll(self.mockSignIn); +} + - (void)testSignInAlreadyGranted { id mockUser = OCMClassMock([GIDGoogleUser class]); OCMStub([mockUser userID]).andReturn(@"mockID"); @@ -327,6 +362,7 @@ - (void)testSignInAlreadyGranted { [self configureMock:[self.mockSignIn stub] forSignInWithHint:nil additionalScopes:OCMOCK_ANY + nonce:nil completion:[OCMArg invokeBlockWithArgs:mockSignInResult, [NSNull null], nil]]; NSError *sdkError = [NSError errorWithDomain:kGIDSignInErrorDomain @@ -355,6 +391,7 @@ - (void)testSignInError { [self configureMock:[self.mockSignIn stub] forSignInWithHint:nil additionalScopes:OCMOCK_ANY + nonce:nil completion:[OCMArg invokeBlockWithArgs:[NSNull null], sdkError, nil]]; XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"]; @@ -375,6 +412,7 @@ - (void)testSignInExceptionReturnsError { OCMExpect([self configureMock:self.mockSignIn forSignInWithHint:OCMOCK_ANY additionalScopes:OCMOCK_ANY + nonce:nil completion:OCMOCK_ANY]) .andThrow([NSException exceptionWithName:@"MockName" reason:@"MockReason" userInfo:nil]); @@ -642,17 +680,20 @@ - (void)configureMock:(id)mock - (void)configureMock:(id)mock forSignInWithHint:(NSString *)hint additionalScopes:(NSArray *)additionalScopes + nonce:(nullable NSString *)nonce completion:(nullable void (^)(GIDSignInResult *_Nullable signInResult, NSError *_Nullable error))completion { #if TARGET_OS_OSX [mock signInWithPresentingWindow:OCMOCK_ANY hint:hint additionalScopes:additionalScopes + nonce:nonce completion:completion]; #else [mock signInWithPresentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]] hint:hint additionalScopes:additionalScopes + nonce:nonce completion:completion]; #endif } diff --git a/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios.podspec b/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios.podspec index b6c8e728d9c..311919b1498 100644 --- a/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios.podspec +++ b/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios.podspec @@ -16,11 +16,10 @@ Enables Google Sign-In in Flutter apps. s.public_header_files = 'google_sign_in_ios/Sources/google_sign_in_ios/include/**/*.h' s.module_map = 'google_sign_in_ios/Sources/google_sign_in_ios/include/FLTGoogleSignInPlugin.modulemap' - # AppAuth and GTMSessionFetcher are GoogleSignIn transitive dependencies. - # Depend on versions which defines modules. - s.dependency 'AppAuth', '>= 1.7.4' + # GTMSessionFetcher is a GoogleSignIn transitive dependency, added here as a + # direct dependency to ensure a version which defines modules. s.dependency 'GTMSessionFetcher', '>= 3.4.0' - s.dependency 'GoogleSignIn', '~> 8.0' + s.dependency 'GoogleSignIn', '~> 9.0' s.static_framework = true s.ios.dependency 'Flutter' s.osx.dependency 'FlutterMacOS' diff --git a/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Package.swift b/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Package.swift index f41e40ec679..a4e3e726aba 100644 --- a/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Package.swift +++ b/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Package.swift @@ -18,7 +18,7 @@ let package = Package( dependencies: [ .package( url: "https://github.com/google/GoogleSignIn-iOS.git", - from: "8.0.0") + from: "9.0.0") ], targets: [ .target( diff --git a/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Sources/google_sign_in_ios/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Sources/google_sign_in_ios/FLTGoogleSignInPlugin.m index 07c392e0771..0b47b2e5ea1 100644 --- a/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Sources/google_sign_in_ios/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in_ios/darwin/google_sign_in_ios/Sources/google_sign_in_ios/FLTGoogleSignInPlugin.m @@ -276,18 +276,17 @@ - (void)signInWithHint:(nullable NSString *)hint nonce:(nullable NSString *)nonce completion:(void (^)(GIDSignInResult *_Nullable signInResult, NSError *_Nullable error))completion { - // TODO(stuartmorgan): Add the nonce parameter to the calls below once it's available; it was - // added after 8.0, and based on https://github.com/google/GoogleSignIn-iOS/releases appears to - // be slated for an 8.1 release. See https://github.com/flutter/flutter/issues/85439. #if TARGET_OS_OSX [self.signIn signInWithPresentingWindow:self.registrar.view.window hint:hint additionalScopes:additionalScopes + nonce:nonce completion:completion]; #else [self.signIn signInWithPresentingViewController:[self topViewController] hint:hint additionalScopes:additionalScopes + nonce:nonce completion:completion]; #endif } diff --git a/packages/google_sign_in/google_sign_in_ios/pubspec.yaml b/packages/google_sign_in/google_sign_in_ios/pubspec.yaml index f38a2eb2c77..a4f3f2d7baf 100644 --- a/packages/google_sign_in/google_sign_in_ios/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in_ios/pubspec.yaml @@ -2,7 +2,7 @@ name: google_sign_in_ios description: iOS implementation of the google_sign_in plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 6.0.1 +version: 6.1.0 environment: sdk: ^3.6.0 From eaa404485e52c57e573cad12ab73c3005b79b4b3 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 21 Jul 2025 10:54:13 -0400 Subject: [PATCH 2/2] Add assertion for Gemini --- .../google_sign_in_ios/darwin/Tests/GoogleSignInTests.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m b/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m index 34ef4472e40..f82fd56e01a 100644 --- a/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m +++ b/packages/google_sign_in/google_sign_in_ios/darwin/Tests/GoogleSignInTests.m @@ -291,6 +291,7 @@ - (void)testSignInWithScopeHint { serverClientId:nil hostedDomain:nil] error:&initializationError]; + XCTAssertNil(initializationError); id mockUser = OCMClassMock([GIDGoogleUser class]); OCMStub([mockUser userID]).andReturn(@"mockID"); @@ -326,6 +327,7 @@ - (void)testSignInWithNonce { serverClientId:nil hostedDomain:nil] error:&initializationError]; + XCTAssertNil(initializationError); id mockUser = OCMClassMock([GIDGoogleUser class]); OCMStub([mockUser userID]).andReturn(@"mockID");