3
3
// found in the LICENSE file.
4
4
5
5
#import " FLTGoogleSignInPlugin.h"
6
+ #import " FLTGoogleSignInPlugin_Test.h"
7
+
6
8
#import < GoogleSignIn/GoogleSignIn.h>
7
9
8
10
// The key within `GoogleService-Info.plist` used to hold the application's
35
37
}
36
38
37
39
@interface FLTGoogleSignInPlugin () <GIDSignInDelegate>
40
+ @property (strong , readonly ) GIDSignIn *signIn;
41
+
42
+ // Redeclared as not a designated initializer.
43
+ - (instancetype )init ;
38
44
@end
39
45
40
46
@implementation FLTGoogleSignInPlugin {
41
47
FlutterResult _accountRequest;
42
- NSArray *_additionalScopesRequest;
48
+ NSArray < NSString *> *_additionalScopesRequest;
43
49
}
44
50
45
51
+ (void )registerWithRegistrar : (NSObject <FlutterPluginRegistrar> *)registrar {
@@ -52,9 +58,14 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
52
58
}
53
59
54
60
- (instancetype )init {
61
+ return [self initWithSignIn: GIDSignIn.sharedInstance];
62
+ }
63
+
64
+ - (instancetype )initWithSignIn : (GIDSignIn *)signIn {
55
65
self = [super init ];
56
66
if (self) {
57
- [GIDSignIn sharedInstance ].delegate = self;
67
+ _signIn = signIn;
68
+ _signIn.delegate = self;
58
69
59
70
// On the iOS simulator, we get "Broken pipe" errors after sign-in for some
60
71
// unknown reason. We can avoid crashing the app by ignoring them.
@@ -76,22 +87,22 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
76
87
NSString *path = [[NSBundle mainBundle ] pathForResource: @" GoogleService-Info"
77
88
ofType: @" plist" ];
78
89
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 ]];
82
93
83
94
if (hasDynamicClientId) {
84
- [GIDSignIn sharedInstance ]. clientID = [ call.arguments valueForKey: @" clientId" ];
95
+ self. signIn . clientID = call.arguments [ @" clientId" ];
85
96
} else {
86
- [GIDSignIn sharedInstance ] .clientID = plist[kClientIdKey ];
97
+ self. signIn .clientID = plist[kClientIdKey ];
87
98
}
88
99
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" ];
91
102
if (call.arguments [@" hostedDomain" ] == [NSNull null ]) {
92
- [GIDSignIn sharedInstance ] .hostedDomain = nil ;
103
+ self. signIn .hostedDomain = nil ;
93
104
} else {
94
- [GIDSignIn sharedInstance ] .hostedDomain = call.arguments [@" hostedDomain" ];
105
+ self. signIn .hostedDomain = call.arguments [@" hostedDomain" ];
95
106
}
96
107
result (nil );
97
108
} else {
@@ -102,23 +113,23 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
102
113
}
103
114
} else if ([call.method isEqualToString: @" signInSilently" ]) {
104
115
if ([self setAccountRequest: result]) {
105
- [[GIDSignIn sharedInstance ] restorePreviousSignIn ];
116
+ [self .signIn restorePreviousSignIn ];
106
117
}
107
118
} else if ([call.method isEqualToString: @" isSignedIn" ]) {
108
- result (@([[GIDSignIn sharedInstance ] hasPreviousSignIn ]));
119
+ result (@([self .signIn hasPreviousSignIn ]));
109
120
} else if ([call.method isEqualToString: @" signIn" ]) {
110
- [GIDSignIn sharedInstance ] .presentingViewController = [self topViewController ];
121
+ self. signIn .presentingViewController = [self topViewController ];
111
122
112
123
if ([self setAccountRequest: result]) {
113
124
@try {
114
- [[GIDSignIn sharedInstance ] signIn ];
125
+ [self .signIn signIn ];
115
126
} @catch (NSException *e) {
116
127
result ([FlutterError errorWithCode: @" google_sign_in" message: e.reason details: e.name]);
117
128
[e raise ];
118
129
}
119
130
}
120
131
} else if ([call.method isEqualToString: @" getTokens" ]) {
121
- GIDGoogleUser *currentUser = [GIDSignIn sharedInstance ] .currentUser ;
132
+ GIDGoogleUser *currentUser = self. signIn .currentUser ;
122
133
GIDAuthentication *auth = currentUser.authentication ;
123
134
[auth getTokensWithHandler: ^void (GIDAuthentication *authentication, NSError *error) {
124
135
result (error != nil ? getFlutterError (error) : @{
@@ -127,28 +138,28 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
127
138
});
128
139
}];
129
140
} else if ([call.method isEqualToString: @" signOut" ]) {
130
- [[GIDSignIn sharedInstance ] signOut ];
141
+ [self .signIn signOut ];
131
142
result (nil );
132
143
} else if ([call.method isEqualToString: @" disconnect" ]) {
133
144
if ([self setAccountRequest: result]) {
134
- [[GIDSignIn sharedInstance ] disconnect ];
145
+ [self .signIn disconnect ];
135
146
}
136
147
} else if ([call.method isEqualToString: @" clearAuthCache" ]) {
137
148
// There's nothing to be done here on iOS since the expired/invalid
138
149
// tokens are refreshed automatically by getTokensWithHandler.
139
150
result (nil );
140
151
} else if ([call.method isEqualToString: @" requestScopes" ]) {
141
- GIDGoogleUser *user = [GIDSignIn sharedInstance ] .currentUser ;
152
+ GIDGoogleUser *user = self. signIn .currentUser ;
142
153
if (user == nil ) {
143
154
result ([FlutterError errorWithCode: @" sign_in_required"
144
155
message: @" No account to grant scopes."
145
156
details: nil ]);
146
157
return ;
147
158
}
148
159
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
152
163
filteredArrayUsingPredicate: [NSPredicate
153
164
predicateWithBlock: ^BOOL (id scope, NSDictionary *bindings) {
154
165
return ![user.grantedScopes containsObject: scope];
@@ -161,12 +172,11 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
161
172
162
173
if ([self setAccountRequest: result]) {
163
174
_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 ;
168
178
@try {
169
- [[GIDSignIn sharedInstance ] signIn ];
179
+ [self .signIn signIn ];
170
180
} @catch (NSException *e) {
171
181
result ([FlutterError errorWithCode: @" request_scopes" message: e.reason details: e.name]);
172
182
}
@@ -187,8 +197,10 @@ - (BOOL)setAccountRequest:(FlutterResult)request {
187
197
return YES ;
188
198
}
189
199
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];
192
204
}
193
205
194
206
#pragma mark - <GIDSignInUIDelegate> protocol
@@ -251,7 +263,7 @@ - (void)signIn:(GIDSignIn *)signIn
251
263
252
264
#pragma mark - private methods
253
265
254
- - (void )respondWithAccount : (id )account error : (NSError *)error {
266
+ - (void )respondWithAccount : (NSDictionary <NSString *, id> * )account error : (NSError *)error {
255
267
FlutterResult result = _accountRequest;
256
268
_accountRequest = nil ;
257
269
result (error != nil ? getFlutterError (error) : account);
0 commit comments