33// found in the LICENSE file.
44
55#import " FLTGoogleSignInPlugin.h"
6+ #import " FLTGoogleSignInPlugin_Test.h"
7+
68#import < GoogleSignIn/GoogleSignIn.h>
79
810// The key within `GoogleService-Info.plist` used to hold the application's
3537}
3638
3739@interface FLTGoogleSignInPlugin () <GIDSignInDelegate>
40+ @property (strong , readonly ) GIDSignIn *signIn;
41+
42+ // Redeclared as not a designated initializer.
43+ - (instancetype )init ;
3844@end
3945
4046@implementation FLTGoogleSignInPlugin {
4147 FlutterResult _accountRequest;
42- NSArray *_additionalScopesRequest;
48+ NSArray < NSString *> *_additionalScopesRequest;
4349}
4450
4551+ (void )registerWithRegistrar : (NSObject <FlutterPluginRegistrar> *)registrar {
@@ -52,9 +58,14 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
5258}
5359
5460- (instancetype )init {
61+ return [self initWithSignIn: GIDSignIn.sharedInstance];
62+ }
63+
64+ - (instancetype )initWithSignIn : (GIDSignIn *)signIn {
5565 self = [super init ];
5666 if (self) {
57- [GIDSignIn sharedInstance ].delegate = self;
67+ _signIn = signIn;
68+ _signIn.delegate = self;
5869
5970 // On the iOS simulator, we get "Broken pipe" errors after sign-in for some
6071 // unknown reason. We can avoid crashing the app by ignoring them.
@@ -76,22 +87,22 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
7687 NSString *path = [[NSBundle mainBundle ] pathForResource: @" GoogleService-Info"
7788 ofType: @" plist" ];
7889 if (path) {
79- NSMutableDictionary *plist = [[ NSMutableDictionary alloc ] initWithContentsOfFile: path];
80- BOOL hasDynamicClientId =
81- [[ call.arguments valueForKey: @" clientId" ] isKindOfClass: [NSString class ]];
90+ NSMutableDictionary < NSString *, NSString *> *plist =
91+ [[ NSMutableDictionary alloc ] initWithContentsOfFile: path];
92+ BOOL hasDynamicClientId = [ call.arguments[ @" clientId" ] isKindOfClass: [NSString class ]];
8293
8394 if (hasDynamicClientId) {
84- [GIDSignIn sharedInstance ]. clientID = [ call.arguments valueForKey: @" clientId" ];
95+ self. signIn . clientID = call.arguments [ @" clientId" ];
8596 } else {
86- [GIDSignIn sharedInstance ] .clientID = plist[kClientIdKey ];
97+ self. signIn .clientID = plist[kClientIdKey ];
8798 }
8899
89- [GIDSignIn sharedInstance ] .serverClientID = plist[kServerClientIdKey ];
90- [GIDSignIn sharedInstance ] .scopes = call.arguments [@" scopes" ];
100+ self. signIn .serverClientID = plist[kServerClientIdKey ];
101+ self. signIn .scopes = call.arguments [@" scopes" ];
91102 if (call.arguments [@" hostedDomain" ] == [NSNull null ]) {
92- [GIDSignIn sharedInstance ] .hostedDomain = nil ;
103+ self. signIn .hostedDomain = nil ;
93104 } else {
94- [GIDSignIn sharedInstance ] .hostedDomain = call.arguments [@" hostedDomain" ];
105+ self. signIn .hostedDomain = call.arguments [@" hostedDomain" ];
95106 }
96107 result (nil );
97108 } else {
@@ -102,23 +113,23 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
102113 }
103114 } else if ([call.method isEqualToString: @" signInSilently" ]) {
104115 if ([self setAccountRequest: result]) {
105- [[GIDSignIn sharedInstance ] restorePreviousSignIn ];
116+ [self .signIn restorePreviousSignIn ];
106117 }
107118 } else if ([call.method isEqualToString: @" isSignedIn" ]) {
108- result (@([[GIDSignIn sharedInstance ] hasPreviousSignIn ]));
119+ result (@([self .signIn hasPreviousSignIn ]));
109120 } else if ([call.method isEqualToString: @" signIn" ]) {
110- [GIDSignIn sharedInstance ] .presentingViewController = [self topViewController ];
121+ self. signIn .presentingViewController = [self topViewController ];
111122
112123 if ([self setAccountRequest: result]) {
113124 @try {
114- [[GIDSignIn sharedInstance ] signIn ];
125+ [self .signIn signIn ];
115126 } @catch (NSException *e) {
116127 result ([FlutterError errorWithCode: @" google_sign_in" message: e.reason details: e.name]);
117128 [e raise ];
118129 }
119130 }
120131 } else if ([call.method isEqualToString: @" getTokens" ]) {
121- GIDGoogleUser *currentUser = [GIDSignIn sharedInstance ] .currentUser ;
132+ GIDGoogleUser *currentUser = self. signIn .currentUser ;
122133 GIDAuthentication *auth = currentUser.authentication ;
123134 [auth getTokensWithHandler: ^void (GIDAuthentication *authentication, NSError *error) {
124135 result (error != nil ? getFlutterError (error) : @{
@@ -127,28 +138,28 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
127138 });
128139 }];
129140 } else if ([call.method isEqualToString: @" signOut" ]) {
130- [[GIDSignIn sharedInstance ] signOut ];
141+ [self .signIn signOut ];
131142 result (nil );
132143 } else if ([call.method isEqualToString: @" disconnect" ]) {
133144 if ([self setAccountRequest: result]) {
134- [[GIDSignIn sharedInstance ] disconnect ];
145+ [self .signIn disconnect ];
135146 }
136147 } else if ([call.method isEqualToString: @" clearAuthCache" ]) {
137148 // There's nothing to be done here on iOS since the expired/invalid
138149 // tokens are refreshed automatically by getTokensWithHandler.
139150 result (nil );
140151 } else if ([call.method isEqualToString: @" requestScopes" ]) {
141- GIDGoogleUser *user = [GIDSignIn sharedInstance ] .currentUser ;
152+ GIDGoogleUser *user = self. signIn .currentUser ;
142153 if (user == nil ) {
143154 result ([FlutterError errorWithCode: @" sign_in_required"
144155 message: @" No account to grant scopes."
145156 details: nil ]);
146157 return ;
147158 }
148159
149- NSArray * currentScopes = [GIDSignIn sharedInstance ] .scopes ;
150- NSArray *scopes = call.arguments [@" scopes" ];
151- NSArray *missingScopes = [scopes
160+ NSArray < NSString *> * currentScopes = self. signIn .scopes ;
161+ NSArray < NSString *> *scopes = call.arguments [@" scopes" ];
162+ NSArray < NSString *> *missingScopes = [scopes
152163 filteredArrayUsingPredicate: [NSPredicate
153164 predicateWithBlock: ^BOOL (id scope, NSDictionary *bindings) {
154165 return ![user.grantedScopes containsObject: scope];
@@ -161,12 +172,11 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
161172
162173 if ([self setAccountRequest: result]) {
163174 _additionalScopesRequest = missingScopes;
164- [GIDSignIn sharedInstance ].scopes =
165- [currentScopes arrayByAddingObjectsFromArray: missingScopes];
166- [GIDSignIn sharedInstance ].presentingViewController = [self topViewController ];
167- [GIDSignIn sharedInstance ].loginHint = user.profile .email ;
175+ self.signIn .scopes = [currentScopes arrayByAddingObjectsFromArray: missingScopes];
176+ self.signIn .presentingViewController = [self topViewController ];
177+ self.signIn .loginHint = user.profile .email ;
168178 @try {
169- [[GIDSignIn sharedInstance ] signIn ];
179+ [self .signIn signIn ];
170180 } @catch (NSException *e) {
171181 result ([FlutterError errorWithCode: @" request_scopes" message: e.reason details: e.name]);
172182 }
@@ -187,8 +197,10 @@ - (BOOL)setAccountRequest:(FlutterResult)request {
187197 return YES ;
188198}
189199
190- - (BOOL )application : (UIApplication *)app openURL : (NSURL *)url options : (NSDictionary *)options {
191- return [[GIDSignIn sharedInstance ] handleURL: url];
200+ - (BOOL )application : (UIApplication *)app
201+ openURL : (NSURL *)url
202+ options : (NSDictionary <UIApplicationOpenURLOptionsKey, id> *)options {
203+ return [self .signIn handleURL: url];
192204}
193205
194206#pragma mark - <GIDSignInUIDelegate> protocol
@@ -251,7 +263,7 @@ - (void)signIn:(GIDSignIn *)signIn
251263
252264#pragma mark - private methods
253265
254- - (void )respondWithAccount : (id )account error : (NSError *)error {
266+ - (void )respondWithAccount : (NSDictionary <NSString *, id> * )account error : (NSError *)error {
255267 FlutterResult result = _accountRequest;
256268 _accountRequest = nil ;
257269 result (error != nil ? getFlutterError (error) : account);
0 commit comments