Skip to content

Commit 910a7cc

Browse files
authored
Apple signin (#796)
1 parent 8cbf70c commit 910a7cc

26 files changed

+278
-157
lines changed

Auth/FirebaseAuthUI/FUIAuthPickerViewController.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#import "FUIAuthPickerViewController.h"
1818

19+
#import <AuthenticationServices/AuthenticationServices.h>
20+
1921
#import <FirebaseAuth/FirebaseAuth.h>
2022
#import "FUIAuthBaseViewController_Internal.h"
2123
#import "FUIAuthSignInButton.h"

FirebaseUI.podspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ Pod::Spec.new do |s|
133133
oauth.public_header_files = 'OAuth/FirebaseOAuthUI/*.h'
134134
oauth.source_files = 'OAuth/FirebaseOAuthUI/*.{h,m}'
135135
oauth.dependency 'FirebaseUI/Auth'
136+
oauth.resource_bundle = {
137+
'FirebaseOAuthUI' => ['OAuth/FirebaseOAuthUI/**/*.{png,lproj}']
138+
}
136139
oauth.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/FirebaseUI/FirebaseOAuthUI' }
137140
end
138141

OAuth/FirebaseOAuthUI/FUIOAuth.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,31 @@ NS_ASSUME_NONNULL_BEGIN
6161
loginHintKey:(nullable NSString *)loginHintKey
6262
NS_DESIGNATED_INITIALIZER;
6363

64+
/** @fn twitterAuthProvider
65+
@brief Built-in OAuth provider for Twitter.
66+
*/
67+
+ (FUIOAuth *)twitterAuthProvider;
68+
69+
/** @fn githubAuthProvider
70+
@brief Built-in OAuth provider for Github.
71+
*/
72+
+ (FUIOAuth *)githubAuthProvider;
73+
74+
/** @fn microsoftAuthProvider
75+
@brief Built-in OAuth provider for Microsoft.
76+
*/
77+
+ (FUIOAuth *)microsoftAuthProvider;
78+
79+
/** @fn yahooAuthProvider
80+
@brief Built-in OAuth provider for Yahoo.
81+
*/
82+
+ (FUIOAuth *)yahooAuthProvider;
83+
84+
/** @fn appleAuthProvider
85+
@brief Built-in OAuth provider for Apple.
86+
*/
87+
+ (FUIOAuth *)appleAuthProvider API_AVAILABLE(ios(13.0));
88+
6489
@end
6590

6691
NS_ASSUME_NONNULL_END

OAuth/FirebaseOAuthUI/FUIOAuth.m

Lines changed: 143 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#import <FirebaseUI/FirebaseAuthUI.h>
1818

19+
#import <AuthenticationServices/AuthenticationServices.h>
20+
1921
#import "FUIOAuth.h"
2022
#import <FirebaseUI/FUIAuthBaseViewController.h>
2123
#import <FirebaseUI/FUIAuthBaseViewController_Internal.h>
@@ -38,7 +40,9 @@
3840

3941
NS_ASSUME_NONNULL_BEGIN
4042

41-
@interface FUIOAuth ()
43+
@interface FUIOAuth () <ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding> {
44+
FUIAuthProviderSignInCompletionBlock _providerSignInCompletion;
45+
}
4246

4347
/** @property authUI
4448
@brief FUIAuth instance of the application.
@@ -117,12 +121,82 @@ - (instancetype)initWithAuthUI:(FUIAuth *)authUI
117121
_icon = iconImage;
118122
_scopes = scopes;
119123
_customParameters = customParameters;
120-
_provider = [FIROAuthProvider providerWithProviderID:self.providerID];
121124
_loginHintKey = loginHintKey;
125+
if (![_providerID isEqualToString:@"facebook.com"] && ![_providerID isEqualToString:@"apple.com"]) {
126+
_provider = [FIROAuthProvider providerWithProviderID:self.providerID];
127+
}
122128
}
123129
return self;
124130
}
125131

132+
+ (FUIOAuth *)twitterAuthProvider {
133+
return [[FUIOAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]
134+
providerID:@"twitter.com"
135+
buttonLabelText:@"Sign in with Twitter"
136+
shortName:@"Twitter"
137+
buttonColor:[UIColor colorWithRed:71.0f/255.0f
138+
green:154.0f/255.0f
139+
blue:234.0f/255.0f
140+
alpha:1.0f]
141+
iconImage:[FUIAuthUtils imageNamed:@"ic_twitter"
142+
fromBundleNameOrNil:@"FirebaseOAuthUI"]
143+
scopes:@[@"user.readwrite"]
144+
customParameters:@{@"prompt" : @"consent"}
145+
loginHintKey:nil];
146+
}
147+
148+
+ (FUIOAuth *)githubAuthProvider {
149+
return [[FUIOAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]
150+
providerID:@"github.com"
151+
buttonLabelText:@"Sign in with GitHub"
152+
shortName:@"GitHub"
153+
buttonColor:[UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1.0]
154+
iconImage:[FUIAuthUtils imageNamed:@"ic_github"
155+
fromBundleNameOrNil:@"FirebaseOAuthUI"]
156+
scopes:nil
157+
customParameters:nil
158+
loginHintKey:nil];
159+
}
160+
161+
+ (FUIOAuth *)microsoftAuthProvider {
162+
return [[FUIOAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]
163+
providerID:@"microsoft.com"
164+
buttonLabelText:@"Sign in with Microsoft"
165+
shortName:@"Microsoft"
166+
buttonColor:[UIColor colorWithRed:.18 green:.18 blue:.18 alpha:1.0]
167+
iconImage:[FUIAuthUtils imageNamed:@"ic_microsoft"
168+
fromBundleNameOrNil:@"FirebaseOAuthUI"]
169+
scopes:@[@"user.readwrite"]
170+
customParameters:@{@"prompt" : @"consent"}
171+
loginHintKey:@"login_hint"];
172+
}
173+
174+
+ (FUIOAuth *)yahooAuthProvider {
175+
return [[FUIOAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]
176+
providerID:@"yahoo.com"
177+
buttonLabelText:@"Sign in with Yahoo"
178+
shortName:@"Yahoo"
179+
buttonColor:[UIColor colorWithRed:.45 green:.05 blue:.62 alpha:1.0]
180+
iconImage:[FUIAuthUtils imageNamed:@"ic_yahoo"
181+
fromBundleNameOrNil:@"FirebaseOAuthUI"]
182+
scopes:@[@"user.readwrite"]
183+
customParameters:@{@"prompt" : @"consent"}
184+
loginHintKey:nil];
185+
}
186+
187+
+ (FUIOAuth *)appleAuthProvider {
188+
return [[FUIOAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]
189+
providerID:@"apple.com"
190+
buttonLabelText:@"Sign in with Apple"
191+
shortName:@"Apple"
192+
buttonColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]
193+
iconImage:[FUIAuthUtils imageNamed:@"ic_apple"
194+
fromBundleNameOrNil:@"FirebaseOAuthUI"]
195+
scopes:@[@"name", @"email"]
196+
customParameters:nil
197+
loginHintKey:nil];
198+
}
199+
126200
#pragma mark - FUIAuthProvider
127201

128202
/** @fn accessToken:
@@ -158,41 +232,55 @@ - (void)signInWithDefaultValue:(nullable NSString *)defaultValue
158232
presentingViewController:(nullable UIViewController *)presentingViewController
159233
completion:(nullable FUIAuthProviderSignInCompletionBlock)completion {
160234
self.presentingViewController = presentingViewController;
161-
162235
FIROAuthProvider *provider = self.provider;
163-
provider.scopes = self.scopes;
164-
NSMutableDictionary *customParameters = [NSMutableDictionary dictionary];
165-
if (self.customParameters.count) {
166-
[customParameters addEntriesFromDictionary:self.customParameters];
167-
}
168-
if (self.loginHintKey.length && defaultValue.length) {
169-
customParameters[self.loginHintKey] = defaultValue;
170-
}
171-
provider.customParameters = [customParameters copy];
172-
173-
[self.provider getCredentialWithUIDelegate:nil
174-
completion:^(FIRAuthCredential *_Nullable credential,
175-
NSError *_Nullable error) {
176-
if (error) {
177-
[FUIAuthBaseViewController showAlertWithMessage:error.localizedDescription
178-
presentingViewController:presentingViewController];
179-
if (completion) {
180-
completion(nil, error, nil, nil);
181-
}
182-
return;
236+
_providerSignInCompletion = completion;
237+
238+
if ([self.providerID isEqualToString:@"apple.com"]) {
239+
if (@available(iOS 13.0, *)) {
240+
ASAuthorizationAppleIDRequest *request = [[[ASAuthorizationAppleIDProvider alloc] init] createRequest];
241+
request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
242+
ASAuthorizationController* controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
243+
controller.delegate = self;
244+
controller.presentationContextProvider = self;
245+
[controller performRequests];
246+
} else {
247+
NSLog(@"Sign in with Apple is only available on iOS 13+.");
183248
}
184-
if (completion) {
185-
UIActivityIndicatorView *activityView =
186-
[FUIAuthBaseViewController addActivityIndicator:presentingViewController.view];
187-
[activityView startAnimating];
188-
FIRAuthResultCallback result = ^(FIRUser *_Nullable user,
189-
NSError *_Nullable error) {
190-
[activityView stopAnimating];
191-
[activityView removeFromSuperview];
192-
};
193-
completion(credential, nil, result, nil);
249+
} else {
250+
provider.scopes = self.scopes;
251+
NSMutableDictionary *customParameters = [NSMutableDictionary dictionary];
252+
if (self.customParameters.count) {
253+
[customParameters addEntriesFromDictionary:self.customParameters];
194254
}
195-
}];
255+
if (self.loginHintKey.length && defaultValue.length) {
256+
customParameters[self.loginHintKey] = defaultValue;
257+
}
258+
provider.customParameters = [customParameters copy];
259+
260+
[self.provider getCredentialWithUIDelegate:nil
261+
completion:^(FIRAuthCredential *_Nullable credential,
262+
NSError *_Nullable error) {
263+
if (error) {
264+
[FUIAuthBaseViewController showAlertWithMessage:error.localizedDescription
265+
presentingViewController:presentingViewController];
266+
if (completion) {
267+
completion(nil, error, nil, nil);
268+
}
269+
return;
270+
}
271+
if (completion) {
272+
UIActivityIndicatorView *activityView =
273+
[FUIAuthBaseViewController addActivityIndicator:presentingViewController.view];
274+
[activityView startAnimating];
275+
FIRAuthResultCallback result = ^(FIRUser *_Nullable user,
276+
NSError *_Nullable error) {
277+
[activityView stopAnimating];
278+
[activityView removeFromSuperview];
279+
};
280+
completion(credential, nil, result, nil);
281+
}
282+
}];
283+
}
196284
}
197285

198286
- (void)signOut {
@@ -212,6 +300,27 @@ - (BOOL)handleOpenURL:(NSURL *)URL sourceApplication:(nullable NSString *)source
212300
return NO;
213301
}
214302

303+
#pragma mark - ASAuthorizationControllerDelegate
304+
305+
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
306+
ASAuthorizationAppleIDCredential* appleIDCredential = authorization.credential;
307+
NSString *idToken = [NSString stringWithUTF8String:[appleIDCredential.identityToken bytes]];
308+
FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com"
309+
IDToken:idToken
310+
accessToken:nil];
311+
_providerSignInCompletion(credential, nil, nil, nil);
312+
}
313+
314+
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {
315+
NSLog(@"%@", error.description);
316+
}
317+
318+
#pragma mark - ASAuthorizationControllerPresentationContextProviding
319+
320+
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)) {
321+
return self.presentingViewController.view.window;
322+
}
323+
215324
@end
216325

217326
NS_ASSUME_NONNULL_END
1.29 KB
Loading
1.72 KB
Loading
2.46 KB
Loading
800 Bytes
Loading
1.75 KB
Loading
3.03 KB
Loading

0 commit comments

Comments
 (0)