Explorar el Código

Implement -restorePreviousSignInWithCallback:

Peter Andrews hace 4 años
padre
commit
fc4fa834ac

+ 17 - 5
GoogleSignIn/Sources/GIDSignIn.m

@@ -197,8 +197,8 @@ static const NSTimeInterval kMinimumRestoredAccessTokenTimeToExpire = 600.0;
                                       profileData:nil];
 }
 
-- (void)restorePreviousSignIn {
-  [self signInWithOptions:[GIDSignInInternalOptions silentOptions]];
+- (void)restorePreviousSignInWithCallback:(GIDSignInCallback)callback {
+  [self signInWithOptions:[GIDSignInInternalOptions silentOptionsWithCallback:callback]];
 }
 
 // Authenticates the user by first searching the keychain, then attempting to retrieve the refresh
@@ -360,7 +360,11 @@ static const NSTimeInterval kMinimumRestoredAccessTokenTimeToExpire = 600.0;
       if (error) {
         [self authenticateWithOptions:options];
       } else {
-        [_delegate signIn:self didSignInForUser:_currentUser withError:nil];
+        if (options.callback) {
+          options.callback(_currentUser, nil);
+        } else {
+          [_delegate signIn:self didSignInForUser:_currentUser withError:nil];
+        }
       }
     }];
   } else {
@@ -465,7 +469,11 @@ static const NSTimeInterval kMinimumRestoredAccessTokenTimeToExpire = 600.0;
     NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
                                          code:kGIDSignInErrorCodeHasNoAuthInKeychain
                                      userInfo:nil];
-    [_delegate signIn:self didSignInForUser:nil withError:error];
+    if (options.callback) {
+      options.callback(nil, error);
+    } else {
+      [_delegate signIn:self didSignInForUser:nil withError:error];
+    }
     return;
   }
 
@@ -630,7 +638,11 @@ static const NSTimeInterval kMinimumRestoredAccessTokenTimeToExpire = 600.0;
   __weak GIDAuthFlow *weakAuthFlow = authFlow;
   [authFlow addCallback:^() {
     GIDAuthFlow *handlerAuthFlow = weakAuthFlow;
-    [_delegate signIn:self didSignInForUser:_currentUser withError:handlerAuthFlow.error];
+    if (_currentOptions.callback) {
+      _currentOptions.callback(_currentUser, handlerAuthFlow.error);
+    } else {
+      [_delegate signIn:self didSignInForUser:_currentUser withError:handlerAuthFlow.error];
+    }
   }];
 }
 

+ 6 - 1
GoogleSignIn/Sources/GIDSignInInternalOptions.h

@@ -16,6 +16,8 @@
 
 #import <Foundation/Foundation.h>
 
+#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h"
+
 NS_ASSUME_NONNULL_BEGIN
 
 /// The options used internally for aspects of the sign-in flow.
@@ -30,11 +32,14 @@ NS_ASSUME_NONNULL_BEGIN
 /// The extra parameters used in the sign-in URL.
 @property(nonatomic, readonly, nullable) NSDictionary *extraParams;
 
+/// The callback block to be called at the completion of the flow.
+@property(nonatomic, readonly, nullable) GIDSignInCallback callback;
+
 /// Creates the default options.
 + (instancetype)defaultOptions;
 
 /// Creates the options to sign in silently.
-+ (instancetype)silentOptions;
++ (instancetype)silentOptionsWithCallback:(GIDSignInCallback)callback;
 
 /// Creates the options to sign in with extra parameters.
 + (instancetype)optionsWithExtraParams:(NSDictionary *)extraParams;

+ 2 - 1
GoogleSignIn/Sources/GIDSignInInternalOptions.m

@@ -27,10 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
   return options;
 }
 
-+ (instancetype)silentOptions {
++ (instancetype)silentOptionsWithCallback:(GIDSignInCallback)callback {
   GIDSignInInternalOptions *options = [self defaultOptions];
   if (options) {
     options->_interactive = NO;
+    options->_callback = callback;
   }
   return options;
 }

+ 4 - 5
GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h

@@ -150,10 +150,9 @@ typedef void (^GIDSignInCallback)(GIDGoogleUser *_Nullable user, NSError *_Nulla
 - (BOOL)hasPreviousSignIn;
 
 /// Attempts to restore a previously authenticated user without interaction.
-
-/// The delegate will be called at the end of this process indicating success or failure.  The
-/// current values of `GIDSignIn`'s configuration properties will not impact the restored user.
-- (void)restorePreviousSignIn;
+///
+/// @param callback The `GIDSignInCallback` block that is called on completion.
+- (void)restorePreviousSignInWithCallback:(GIDSignInCallback)callback;
 
 /// Starts an interactive sign-in flow using `GIDSignIn`'s configuration properties.
 ///
@@ -168,7 +167,7 @@ typedef void (^GIDSignInCallback)(GIDGoogleUser *_Nullable user, NSError *_Nulla
 
 /// Disconnects the current user from the app and revokes previous authentication. If the operation
 /// succeeds, the OAuth 2.0 token is also removed from keychain.
-/// 
+///
 /// @param callback The `GIDSignInCallback` block that is called on completion.
 - (void)disconnectWithCallback:(GIDSignInCallback)callback;
 

+ 3 - 1
GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m

@@ -29,10 +29,12 @@
 }
 
 - (void)testSilentOptions {
-  GIDSignInInternalOptions *options = [GIDSignInInternalOptions silentOptions];
+  GIDSignInCallback callback = ^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) {};
+  GIDSignInInternalOptions *options = [GIDSignInInternalOptions silentOptionsWithCallback:callback];
   XCTAssertFalse(options.interactive);
   XCTAssertFalse(options.continuation);
   XCTAssertNil(options.extraParams);
+  XCTAssertEqual(options.callback, callback);
 }
 
 - (void)testSilentOptionsWithExtraParams {

+ 46 - 17
GoogleSignIn/Tests/Unit/GIDSignInTest.m

@@ -398,18 +398,23 @@ static void *kTestObserverContext = &kTestObserverContext;
   _delegateCalled = NO;
   _authError = nil;
 
-  [_signIn restorePreviousSignIn];
+  XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called."];
+
+  [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user,
+                                               NSError * _Nullable error) {
+    [expectation fulfill];
+    XCTAssertNotNil(error, @"error should not have been nil");
+    XCTAssertEqual(error.domain,
+                   kGIDSignInErrorDomain,
+                   @"error domain should have been the sign-in error domain.");
+    XCTAssertEqual(error.code,
+                   kGIDSignInErrorCodeHasNoAuthInKeychain,
+                   @"error code should have been the 'NoAuthInKeychain' error code.");
+  }];
 
+  [self waitForExpectationsWithTimeout:1 handler:nil];
   [_authorization verify];
   [_authState verify];
-  XCTAssertTrue(_delegateCalled, @"should have called delegate");
-  XCTAssertNotNil(_authError, @"error should not have been nil");
-  XCTAssertEqual(_authError.domain,
-                 kGIDSignInErrorDomain,
-                 @"error domain should have been the sign-in error domain.");
-  XCTAssertEqual(_authError.code,
-                 kGIDSignInErrorCodeHasNoAuthInKeychain,
-                 @"error code should have been the 'NoAuthInKeychain' error code.");
 }
 
 // Verifies |shouldFetchBasicProfile| is default YES.
@@ -696,8 +701,15 @@ static void *kTestObserverContext = &kTestObserverContext;
   [[[_authState expect] andReturnValue:[NSNumber numberWithBool:NO]] isAuthorized];
 
   _signIn.presentingViewController = nil;
-  [_signIn restorePreviousSignIn];
 
+  XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called."];
+
+  [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user,
+                                               NSError * _Nullable error) {
+    [expectation fulfill];
+  }];
+
+  [self waitForExpectationsWithTimeout:1 handler:nil];
   [_authorization verify];
   [_authState verify];
 }
@@ -1022,7 +1034,12 @@ static void *kTestObserverContext = &kTestObserverContext;
   }
 
   if (restoredSignIn && oldAccessToken) {
-    [_signIn restorePreviousSignIn];
+    XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called"];
+    [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user,
+                                                 NSError * _Nullable error) {
+      [expectation fulfill];
+      XCTAssertNil(error, @"should have no error");
+    }];
   }
 
   if (!restoredSignIn || (restoredSignIn && oldAccessToken)) {
@@ -1058,7 +1075,12 @@ static void *kTestObserverContext = &kTestObserverContext;
   }
 
   if (restoredSignIn && !oldAccessToken) {
-    [_signIn restorePreviousSignIn];
+    XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called"];
+    [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user,
+                                                 NSError * _Nullable error) {
+      [expectation fulfill];
+      XCTAssertNil(error, @"should have no error");
+    }];
   } else {
     // Simulate token endpoint response.
     _savedTokenCallback(tokenResponse, nil);
@@ -1068,9 +1090,10 @@ static void *kTestObserverContext = &kTestObserverContext;
   if (keychainError) {
     return;
   }
+  if (restoredSignIn) {
+    [self waitForExpectationsWithTimeout:1 handler:nil];
+  }
   XCTAssertTrue(_keychainSaved, @"should save to keychain");
-  XCTAssertTrue(_delegateCalled, @"should call delegate");
-  XCTAssertNil(_authError, @"should have no error");
   XCTAssertNotNil(authState);
   // Check fat ID token decoding
   XCTAssertEqualObjects(profileData.name, kFatName);
@@ -1088,13 +1111,19 @@ static void *kTestObserverContext = &kTestObserverContext;
   __block GIDAuthenticationAction action;
   [[_authentication expect] doWithFreshTokens:SAVE_TO_ARG_BLOCK(action)];
 
-  [_signIn restorePreviousSignIn];
+  XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called"];
+
+  [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user,
+                                               NSError * _Nullable error) {
+    [expectation fulfill];
+    XCTAssertNil(error, @"should have no error");
+  }];
+
   action(_authentication, nil);
 
+  [self waitForExpectationsWithTimeout:1 handler:nil];
   XCTAssertFalse(_keychainRemoved, @"should not remove keychain");
   XCTAssertFalse(_keychainSaved, @"should not save to keychain again");
-  XCTAssertTrue(_delegateCalled, @"should call delegate");
-  XCTAssertNil(_authError, @"should have no error");
 }
 
 

+ 13 - 11
Sample/Source/AppDelegate.m

@@ -33,17 +33,19 @@ static NSString * const kClientID =
     didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   // Set app's client ID for |GIDSignIn|.
   [GIDSignIn sharedInstance].clientID = kClientID;
-
-  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
-  SignInViewController *masterViewController =
-      [[SignInViewController alloc] initWithNibName:@"SignInViewController"
-                                             bundle:nil];
-  self.navigationController =
-      [[UINavigationController alloc]
-          initWithRootViewController:masterViewController];
-  self.window.rootViewController = self.navigationController;
-  [self.window makeKeyAndVisible];
-
+  // Restore any previous sign-in session before displaying main view.
+  [[GIDSignIn sharedInstance] restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user,
+                                                                  NSError * _Nullable error) {
+    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+    SignInViewController *masterViewController =
+        [[SignInViewController alloc] initWithNibName:@"SignInViewController"
+                                               bundle:nil];
+    self.navigationController =
+        [[UINavigationController alloc]
+            initWithRootViewController:masterViewController];
+    self.window.rootViewController = self.navigationController;
+    [self.window makeKeyAndVisible];
+  }];
   return YES;
 }