diff --git a/FirebaseAuthUI/AccountManagement/FUIAccountSettingsOperation.m b/FirebaseAuthUI/AccountManagement/FUIAccountSettingsOperation.m index 908e463ab45..dbbbf266bc6 100644 --- a/FirebaseAuthUI/AccountManagement/FUIAccountSettingsOperation.m +++ b/FirebaseAuthUI/AccountManagement/FUIAccountSettingsOperation.m @@ -165,7 +165,7 @@ - (void)reauthenticateWithProvider:(NSString *)providerID [self.delegate incrementActivity]; // Sign out first to make sure sign in starts with a clean state. [providerUI signOut]; - [providerUI signInWithEmail:self.delegate.auth.currentUser.email + [providerUI signInWithDefaultValue:self.delegate.auth.currentUser.email presentingViewController:[self.delegate presentingController] completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error, diff --git a/FirebaseAuthUI/FUIAuth.m b/FirebaseAuthUI/FUIAuth.m index 424380d0d00..4c891c76e2d 100644 --- a/FirebaseAuthUI/FUIAuth.m +++ b/FirebaseAuthUI/FUIAuth.m @@ -128,11 +128,12 @@ - (BOOL)signOutWithError:(NSError *_Nullable *_Nullable)error { } - (void)signInWithProviderUI:(id)providerUI - presentingViewController:(UIViewController *)presentingViewController { + presentingViewController:(UIViewController *)presentingViewController + defaultValue:(nullable NSString *)defaultValue { // Sign out first to make sure sign in starts with a clean state. [providerUI signOut]; - [providerUI signInWithEmail:nil + [providerUI signInWithDefaultValue:defaultValue presentingViewController:presentingViewController completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error, @@ -247,7 +248,7 @@ - (void)handleAccountLinkingForEmail:(NSString *)email signinHandler:^{ // Sign out first to make sure sign in starts with a clean state. [bestProvider signOut]; - [bestProvider signInWithEmail:email + [bestProvider signInWithDefaultValue:email presentingViewController:presentingViewController completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error, diff --git a/FirebaseAuthUI/FUIAuthPickerViewController.m b/FirebaseAuthUI/FUIAuthPickerViewController.m index 6e4b00efcbb..bff85c44aa2 100644 --- a/FirebaseAuthUI/FUIAuthPickerViewController.m +++ b/FirebaseAuthUI/FUIAuthPickerViewController.m @@ -152,7 +152,9 @@ - (void)signInWithEmail { } - (void)didTapSignInButton:(FUIAuthSignInButton *)button { - [self.authUI signInWithProviderUI:button.providerUI presentingViewController:self]; + [self.authUI signInWithProviderUI:button.providerUI + presentingViewController:self + defaultValue:nil]; } @end diff --git a/FirebaseAuthUI/FUIAuthProvider.h b/FirebaseAuthUI/FUIAuthProvider.h index 449a5ecce97..f992730b7b7 100644 --- a/FirebaseAuthUI/FUIAuthProvider.h +++ b/FirebaseAuthUI/FUIAuthProvider.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN /** @typedef FIRAuthProviderSignInCompletionBlock @brief The type of block used to notify the auth system of the result of a sign-in flow. - @see FUIAuthProvider.signInWithEmail:presentingViewController:completion: + @see FUIAuthProvider.signInWithDefaultValue:presentingViewController:completion: @param credential The @c FIRAuthCredential object created after user interaction with third party provider. @param error The error which may happen during creation of The @c FIRAuthCredential object. @@ -90,7 +90,26 @@ typedef void (^FIRAuthProviderSignInCompletionBlock) ( */ - (void)signInWithEmail:(nullable NSString *)email presentingViewController:(nullable UIViewController *)presentingViewController - completion:(nullable FIRAuthProviderSignInCompletionBlock)completion; + completion:(nullable FIRAuthProviderSignInCompletionBlock)completion +__attribute__((deprecated("This is deprecated API and will be removed in a future release." + "Use signInWithDefaultValue:presentingViewController:completion:"))); + +/** @fn signInWithDefaultValue:presentingViewController:completion: + @brief Called when the user wants to sign in using this auth provider. + @remarks Implementors should invoke the completion block when the sign-in process has terminated + or is canceled. There are two valid combinations of parameters; either @c credentials and + @c userInfo are both non-nil, or @c error is non-nil. Errors must specify an error code + which is one of the @c FIRAuthErrorCode codes. It is very important that all possible code + paths eventually call this method to inform the auth system of the result of the sign-in + flow. + @param defaultValue The default initialization value of the provider (email, phone number etc.). + @param presentingViewController The view controller used to present the UI. + @param completion See remarks. A block which should be invoked when the sign-in process + (using @c FIRAuthCredential) completes. + */ +- (void)signInWithDefaultValue:(nullable NSString *)defaultValue + presentingViewController:(nullable UIViewController *)presentingViewController + completion:(nullable FIRAuthProviderSignInCompletionBlock)completion; /** @fn signOut @brief Called when the user wants to sign out. diff --git a/FirebaseAuthUI/FUIAuth_Internal.h b/FirebaseAuthUI/FUIAuth_Internal.h index c0dcfa3a239..0bb5c3271c4 100644 --- a/FirebaseAuthUI/FUIAuth_Internal.h +++ b/FirebaseAuthUI/FUIAuth_Internal.h @@ -42,14 +42,17 @@ NS_ASSUME_NONNULL_BEGIN */ - (nullable id)providerWithID:(NSString *)providerID; -/** @fn signInWithProviderUI:presentingViewController: +/** @fn signInWithProviderUI:presentingViewController:defaultValue: @brief Signs in with specified provider. @see FUIAuthDelegate.authUI:didSignInWithUser:error: for method callback. @param providerUI The authentication provider used for signing in. @param presentingViewController The view controller used to present the UI. + @param defaultValue The provider default initialization value (e g email or phone number) + used for signing in. */ - (void)signInWithProviderUI:(id)providerUI - presentingViewController:(UIViewController *)presentingViewController; + presentingViewController:(UIViewController *)presentingViewController + defaultValue:(nullable NSString *)defaultValue; @end diff --git a/FirebaseAuthUI/FUIEmailEntryViewController.m b/FirebaseAuthUI/FUIEmailEntryViewController.m index d6960179682..9b2d86b8a26 100644 --- a/FirebaseAuthUI/FUIEmailEntryViewController.m +++ b/FirebaseAuthUI/FUIEmailEntryViewController.m @@ -255,7 +255,7 @@ - (void)signInWithProvider:(id)provider email:(NSString *)email // Sign out first to make sure sign in starts with a clean state. [provider signOut]; - [provider signInWithEmail:email + [provider signInWithDefaultValue:email presentingViewController:self completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error, diff --git a/FirebaseAuthUI/FUIPasswordSignInViewController.h b/FirebaseAuthUI/FUIPasswordSignInViewController.h index 9210e6e1efa..ecba0309f57 100644 --- a/FirebaseAuthUI/FUIPasswordSignInViewController.h +++ b/FirebaseAuthUI/FUIPasswordSignInViewController.h @@ -71,12 +71,12 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)didChangeEmail:(NSString *)email andPassword:(NSString *)password; -/** @fn signInWithEmail:andPassword: +/** @fn signInWithDefaultValue:andPassword: @brief Should be called when user entered credentials. Sends authorization request @param email The email address of the user. @param password The password which user uses. */ -- (void)signInWithEmail:(NSString *)email andPassword:(NSString *)password; +- (void)signInWithDefaultValue:(NSString *)email andPassword:(NSString *)password; @end diff --git a/FirebaseAuthUI/FUIPasswordSignInViewController.m b/FirebaseAuthUI/FUIPasswordSignInViewController.m index b36b1a60067..e553f4eb174 100644 --- a/FirebaseAuthUI/FUIPasswordSignInViewController.m +++ b/FirebaseAuthUI/FUIPasswordSignInViewController.m @@ -97,7 +97,7 @@ - (void)viewDidLoad { #pragma mark - Actions -- (void)signInWithEmail:(NSString *)email andPassword:(NSString *)password { +- (void)signInWithDefaultValue:(NSString *)email andPassword:(NSString *)password { if (![[self class] isValidEmail:email]) { [self showAlertWithMessage:FUILocalizedString(kStr_InvalidEmailError)]; return; @@ -138,7 +138,7 @@ - (void)signInWithEmail:(NSString *)email andPassword:(NSString *)password { } - (void)signIn { - [self signInWithEmail:_emailField.text andPassword:_passwordField.text]; + [self signInWithDefaultValue:_emailField.text andPassword:_passwordField.text]; } - (void)forgotPasswordForEmail:(NSString *)email { diff --git a/FirebaseFacebookAuthUI/FUIFacebookAuth.m b/FirebaseFacebookAuthUI/FUIFacebookAuth.m index 479929d09a7..dde53cda302 100644 --- a/FirebaseFacebookAuthUI/FUIFacebookAuth.m +++ b/FirebaseFacebookAuthUI/FUIFacebookAuth.m @@ -117,6 +117,14 @@ - (UIColor *)buttonTextColor { - (void)signInWithEmail:(nullable NSString *)email presentingViewController:(nullable UIViewController *)presentingViewController completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { + [self signInWithDefaultValue:email + presentingViewController:presentingViewController + completion:completion]; +} + +- (void)signInWithDefaultValue:(nullable NSString *)defaultValue + presentingViewController:(nullable UIViewController *)presentingViewController + completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { _pendingSignInCallback = completion; _presentingViewController = presentingViewController; diff --git a/FirebaseGoogleAuthUI/FUIGoogleAuth.m b/FirebaseGoogleAuthUI/FUIGoogleAuth.m index c39d2534186..480c42bc063 100644 --- a/FirebaseGoogleAuthUI/FUIGoogleAuth.m +++ b/FirebaseGoogleAuthUI/FUIGoogleAuth.m @@ -106,6 +106,14 @@ - (UIColor *)buttonTextColor { - (void)signInWithEmail:(nullable NSString *)email presentingViewController:(nullable UIViewController *)presentingViewController completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { + [self signInWithDefaultValue:email + presentingViewController:presentingViewController + completion:completion]; +} + +- (void)signInWithDefaultValue:(nullable NSString *)defaultValue + presentingViewController:(nullable UIViewController *)presentingViewController + completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { _presentingViewController = presentingViewController; GIDSignIn *signIn = [self configuredGoogleSignIn]; @@ -118,7 +126,7 @@ - (void)signInWithEmail:(nullable NSString *)email } }; - signIn.loginHint = email; + signIn.loginHint = defaultValue; [signIn signIn]; } diff --git a/FirebasePhoneAuthUI/CountryCode/FUIPhoneNumber.h b/FirebasePhoneAuthUI/CountryCode/FUIPhoneNumber.h new file mode 100644 index 00000000000..23bc19a15b1 --- /dev/null +++ b/FirebasePhoneAuthUI/CountryCode/FUIPhoneNumber.h @@ -0,0 +1,79 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "FUICountryCodes.h" + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString * const FUIPhoneNumberValidationErrorDomain; + +typedef NS_ENUM(NSInteger, FUIPhoneNumberValidationError) { + FUIPhoneNumberValidationErrorMissingPlus = 0, + FUIPhoneNumberValidationErrorMissingDialCode = 1, + FUIPhoneNumberValidationErrorMissingNumber = 2, +}; + +/** Encapsulates a phone number with the raw and the normalized representations */ +@interface FUIPhoneNumber : NSObject + +@property (nonatomic, readonly) FUICountryCodeInfo *countryCode; +@property (nonatomic, copy, readonly) NSString *rawPhoneNumber; +@property (nonatomic, copy, readonly) NSString *normalizedPhoneNumber; + +/** @fn initWithNormalizedPhoneNumber: + @brief Attempts to parse the given phone number into a raw phone number and country code. + Parse behavior: + If given phone number starts with a '+' character, then look for the country code matching + the prefix of the number. + Otherwise use the normalized number as the raw number, and find the country code using the + device locale. + @param normalizedPhoneNumber (required) A phone number string that will be parsed into + a raw phone number and country code. + @return object or nil if any of the required parameters is nil. +*/ +- (instancetype)initWithNormalizedPhoneNumber:(NSString *)normalizedPhoneNumber; + +/** @fn initWithRawPhoneNumber:countryCode: + @param rawPhoneNumber (required) The raw phone number without country code + @param countryCode (required) The country code information + @return object or nil if any of the required parameters is nil. +*/ +- (instancetype)initWithRawPhoneNumber:(NSString *)rawPhoneNumber + countryCode:(FUICountryCodeInfo *)countryCode; + +/** @fn initWithNormalizedPhoneNumber:rawPhoneNumber:countryCode: + @param normalizedPhoneNumber (optional) The phone number returned from the endpoint; + if null or empty it will be computed ('+' + rawCountryCode + rawPhoneNumber) + @param rawPhoneNumber (required) The raw phone number without country code + @param countryCode (required) The country code information + @return object or nil if any of the required parameters is nil. +*/ +- (instancetype)initWithNormalizedPhoneNumber:(NSString *)normalizedPhoneNumber + rawPhoneNumber:(NSString *)rawPhoneNumber + countryCode:(FUICountryCodeInfo *)countryCode; + +- (instancetype)init NS_UNAVAILABLE; + +/** @fn validate: + @brief Checks if current phone number has valid international format. + @param errorRef The error which occurred, if any. + @return True if phone number format is valid. +*/ +- (BOOL)validate:(NSError *__autoreleasing _Nullable *_Nullable)errorRef; +@end + +NS_ASSUME_NONNULL_END diff --git a/FirebasePhoneAuthUI/CountryCode/FUIPhoneNumber.m b/FirebasePhoneAuthUI/CountryCode/FUIPhoneNumber.m new file mode 100644 index 00000000000..00c2774eab4 --- /dev/null +++ b/FirebasePhoneAuthUI/CountryCode/FUIPhoneNumber.m @@ -0,0 +1,120 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "FUIPhoneNumber.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString * const FUIPhoneNumberValidationErrorDomain = @"FUIPhoneNumberValidationErrorDomain"; + +@implementation FUIPhoneNumber + +- (instancetype)initWithNormalizedPhoneNumber:(NSString *)normalizedPhoneNumber { + NSAssert(normalizedPhoneNumber, @"normalizedPhoneNumber can't be nil"); + NSString *rawPhoneNumber; + FUICountryCodes *codes = [[FUICountryCodes alloc] init]; + FUICountryCodeInfo *countryCode = [codes countryCodeInfoForPhoneNumber:normalizedPhoneNumber]; + + if (countryCode) { + // Add 1 for the '+' character + NSInteger countryCodeLength = countryCode.dialCode.length + 1; + if (normalizedPhoneNumber.length >= countryCodeLength) { + rawPhoneNumber = [normalizedPhoneNumber substringFromIndex:countryCodeLength]; + } + } + if (!rawPhoneNumber) { + rawPhoneNumber = normalizedPhoneNumber; + countryCode = [codes countryCodeInfoFromDeviceLocale]; + } + return [self initWithRawPhoneNumber:rawPhoneNumber countryCode:countryCode]; +} + +- (instancetype)initWithNormalizedPhoneNumber:(NSString *)normalizedPhoneNumber + rawPhoneNumber:(NSString *)rawPhoneNumber + countryCode:(FUICountryCodeInfo *)countryCode { + NSAssert(normalizedPhoneNumber, @"normalizedPhoneNumber can't be nil"); + NSAssert(rawPhoneNumber, @"rawPhoneNumber can't be nil"); + NSAssert(countryCode, @"countryCode can't be nil"); + if (self = [super init]) { + _countryCode = countryCode; + _rawPhoneNumber = rawPhoneNumber; + _normalizedPhoneNumber = normalizedPhoneNumber; + } + return self; +} + +- (instancetype)initWithRawPhoneNumber:(NSString *)rawPhoneNumber + countryCode:(FUICountryCodeInfo *)countryCode { + NSAssert(rawPhoneNumber, @"rawPhoneNumber can't be nil"); + NSAssert(countryCode, @"countryCode can't be nil"); + NSString *dialCode = countryCode.dialCode; + NSAssert(dialCode.length, @"dialCode can't be empty"); + if ([dialCode characterAtIndex:0] != '+') { + dialCode = [@"+" stringByAppendingString:dialCode]; + } + NSString *normalizedPhoneNumber = [NSString stringWithFormat:@"%@%@", dialCode, rawPhoneNumber]; + + return [self initWithNormalizedPhoneNumber:normalizedPhoneNumber + rawPhoneNumber:rawPhoneNumber + countryCode:countryCode]; +} + +- (BOOL)validate:(NSError *__autoreleasing _Nullable *_Nullable)errorRef { + // The first character is always the '+' + BOOL firstCharacterIsPlus = [_normalizedPhoneNumber characterAtIndex:0] == '+'; + if (!firstCharacterIsPlus) { + if (errorRef) { + NSString *message = [NSString stringWithFormat:@"Phone number %@ should start with '+'", + _normalizedPhoneNumber]; + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : message }; + *errorRef = [NSError errorWithDomain:FUIPhoneNumberValidationErrorDomain + code:FUIPhoneNumberValidationErrorMissingPlus + userInfo:userInfo]; + } + return false; + } + BOOL containsMoreThanThePlus = self.normalizedPhoneNumber.length > 1; + if (!containsMoreThanThePlus) { + if (errorRef) { + NSString *message = [NSString stringWithFormat:@"Phone number %@ should have only one '+'", + _normalizedPhoneNumber]; + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : message }; + *errorRef = [NSError errorWithDomain:FUIPhoneNumberValidationErrorDomain + code:FUIPhoneNumberValidationErrorMissingDialCode + userInfo:userInfo]; + } + return false; + } + BOOL containsMoreThanTheCountryCode = + self.normalizedPhoneNumber.length > 1 + self.countryCode.dialCode.length; + if (!containsMoreThanTheCountryCode) { + if (errorRef) { + NSString *message = + [NSString stringWithFormat:@"Phone number %@ should have only one country code", + _normalizedPhoneNumber]; + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : message }; + *errorRef = [NSError errorWithDomain:FUIPhoneNumberValidationErrorDomain + code:FUIPhoneNumberValidationErrorMissingNumber + userInfo:userInfo]; + } + return false; + } + return true; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FirebasePhoneAuthUI/FUIPhoneAuth.h b/FirebasePhoneAuthUI/FUIPhoneAuth.h index 090d9f1d739..434d7ea7086 100644 --- a/FirebasePhoneAuthUI/FUIPhoneAuth.h +++ b/FirebasePhoneAuthUI/FUIPhoneAuth.h @@ -38,7 +38,19 @@ NS_ASSUME_NONNULL_BEGIN for method callback. @param presentingViewController The view controller used to present the UI. */ -- (void)signInWithPresentingViewController:(UIViewController *)presentingViewController; +- (void)signInWithPresentingViewController:(UIViewController *)presentingViewController +__attribute__((deprecated("This is deprecated API and will be removed in a future release." + "Please use signInWithPresentingViewController:phoneNumber:"))); + +/** @fn signInWithPresentingViewController:phoneNumber: + @brief Signs in with phone auth provider. @see FUIAuthDelegate.authUI:didSignInWithUser:error: + for method callback. + @param presentingViewController The view controller used to present the UI. + @param phoneNumber The default phone number specified in the international format + e.g. +14151112233 + */ +- (void)signInWithPresentingViewController:(UIViewController *)presentingViewController + phoneNumber:(nullable NSString *)phoneNumber; @end diff --git a/FirebasePhoneAuthUI/FUIPhoneAuth.m b/FirebasePhoneAuthUI/FUIPhoneAuth.m index d4d4f05d584..4b945fa3034 100644 --- a/FirebasePhoneAuthUI/FUIPhoneAuth.m +++ b/FirebasePhoneAuthUI/FUIPhoneAuth.m @@ -81,12 +81,27 @@ - (UIColor *)buttonTextColor { } - (void)signInWithPresentingViewController:(UIViewController *)presentingViewController { - [_authUI signInWithProviderUI:self presentingViewController:presentingViewController]; + [self signInWithPresentingViewController:presentingViewController phoneNumber:nil]; +} + + +- (void)signInWithPresentingViewController:(UIViewController *)presentingViewController + phoneNumber:(nullable NSString *)phoneNumber { + [_authUI signInWithProviderUI:self presentingViewController:presentingViewController + defaultValue:phoneNumber]; } - (void)signInWithEmail:(nullable NSString *)email presentingViewController:(nullable UIViewController *)presentingViewController completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { + [self signInWithDefaultValue:email + presentingViewController:presentingViewController + completion:completion]; +} + +- (void)signInWithDefaultValue:(nullable NSString *)defaultValue + presentingViewController:(nullable UIViewController *)presentingViewController + completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { _pendingSignInCallback = completion; FUIPhoneAuth *delegate = [_authUI providerWithID:FIRPhoneAuthProviderID]; @@ -105,7 +120,8 @@ - (void)signInWithEmail:(nullable NSString *)email return; } - UIViewController *controller = [[FUIPhoneEntryViewController alloc] initWithAuthUI:_authUI]; + UIViewController *controller = [[FUIPhoneEntryViewController alloc] initWithAuthUI:_authUI + phoneNumber:defaultValue]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller]; [presentingViewController presentViewController:navigationController animated:YES completion:nil]; diff --git a/FirebasePhoneAuthUI/FUIPhoneEntryViewController.h b/FirebasePhoneAuthUI/FUIPhoneEntryViewController.h index 35cd1a7fae7..ad76df877e4 100644 --- a/FirebasePhoneAuthUI/FUIPhoneEntryViewController.h +++ b/FirebasePhoneAuthUI/FUIPhoneEntryViewController.h @@ -20,6 +20,45 @@ NS_ASSUME_NONNULL_BEGIN @interface FUIPhoneEntryViewController : FUIAuthBaseViewController +/** @fn initWithNibName:bundle:authUI: + @brief Designated initializer. + @param nibNameOrNil The name of the nib file to associate with the view controller. + @param nibBundleOrNil The bundle in which to search for the nib file. + @param authUI The @c FUIAuth instance that manages this view controller. + */ +- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil + bundle:(nullable NSBundle *)nibBundleOrNil + authUI:(FUIAuth *)authUI +__attribute__((deprecated("This is deprecated API and will be removed in a future release." + "Please use initWithNibName:bundle:authUI:phoneNumber:"))); + +/** @fn initWithAuthUI: + @brief Convenience initializer. + @param authUI The @c FUIAuth instance that manages this view controller. + */ +- (instancetype)initWithAuthUI:(FUIAuth *)authUI +__attribute__((deprecated("This is deprecated API and will be removed in a future release." + "Please use initWithNibName:bundle:authUI:phoneNumber:"))); + +/** @fn initWithAuthUI:phoneNumber: + @brief Convenience initializer. + @param authUI The @c FUIAuth instance that manages this view controller. + @param phoneNumber The phone number which is being verifying. + */ +- (instancetype)initWithAuthUI:(FUIAuth *)authUI + phoneNumber:(nullable NSString *)phoneNumber; + +/** @fn initWithNibName:bundle:authUI:phoneNumber: + @brief Designated initializer. + @param nibNameOrNil The name of the nib file to associate with the view controller. + @param nibBundleOrNil The bundle in which to search for the nib file. + @param authUI The @c FUIAuth instance that manages this view controller. + @param phoneNumber The phone number which is being verifying. + */ +- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil + bundle:(nullable NSBundle *)nibBundleOrNil + authUI:(FUIAuth *)authUI + phoneNumber:(nullable NSString *)phoneNumber NS_DESIGNATED_INITIALIZER; @end NS_ASSUME_NONNULL_END diff --git a/FirebasePhoneAuthUI/FUIPhoneEntryViewController.m b/FirebasePhoneAuthUI/FUIPhoneEntryViewController.m index 5908f5f642a..1c9ce0b98da 100644 --- a/FirebasePhoneAuthUI/FUIPhoneEntryViewController.m +++ b/FirebasePhoneAuthUI/FUIPhoneEntryViewController.m @@ -25,6 +25,7 @@ #import "FUIFeatureSwitch.h" #import "FUIPhoneAuthStrings.h" #import "FUIPhoneAuth_Internal.h" +#import "FUIPhoneNumber.h" #import "FUIPhoneVerificationViewController.h" NS_ASSUME_NONNULL_BEGIN @@ -63,17 +64,37 @@ @implementation FUIPhoneEntryViewController { __weak IBOutlet UITableView *_tableView; __weak IBOutlet UITextView *_tosTextView; FUICountryCodes *_countryCodes; + FUIPhoneNumber *_phoneNumber; +} + +- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil + bundle:(nullable NSBundle *)nibBundleOrNil + authUI:(FUIAuth *)authUI { + return [self initWithNibName:nibNameOrNil + bundle:nibBundleOrNil + authUI:authUI + phoneNumber:nil]; } - (instancetype)initWithAuthUI:(FUIAuth *)authUI { return [self initWithNibName:NSStringFromClass([self class]) bundle:[FUIAuthUtils bundleNamed:FUIPhoneAuthBundleName] - authUI:authUI]; + authUI:authUI + phoneNumber:nil]; +} + +- (instancetype)initWithAuthUI:(FUIAuth *)authUI + phoneNumber:(nullable NSString *)phoneNumber { + return [self initWithNibName:NSStringFromClass([self class]) + bundle:[FUIAuthUtils bundleNamed:FUIPhoneAuthBundleName] + authUI:authUI + phoneNumber:phoneNumber]; } - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil - authUI:(FUIAuth *)authUI { + authUI:(FUIAuth *)authUI + phoneNumber:(nullable NSString *)phoneNumber { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil @@ -81,8 +102,10 @@ - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil if (self) { self.title = FUIPhoneAuthLocalizedString(kPAStr_EnterPhoneTitle); _countryCodes = [[FUICountryCodes alloc] init]; - _selectedCountryCode = [_countryCodes countryCodeInfoFromDeviceLocale]; - + _phoneNumber = phoneNumber.length ? + [[FUIPhoneNumber alloc] initWithNormalizedPhoneNumber:phoneNumber] : nil; + _selectedCountryCode = _phoneNumber.countryCode ?: + [_countryCodes countryCodeInfoFromDeviceLocale]; } return self; } @@ -213,6 +236,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView _phoneNumberField.returnKeyType = UIReturnKeyNext; _phoneNumberField.keyboardType = UIKeyboardTypeNumberPad; [_phoneNumberField becomeFirstResponder]; + if (_phoneNumber) { + _phoneNumberField.text = _phoneNumber.rawPhoneNumber; + } [cell.textField addTarget:self action:@selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged]; diff --git a/FirebaseTwitterAuthUI/FUITwitterAuth.m b/FirebaseTwitterAuthUI/FUITwitterAuth.m index e14ae18b824..68ef0c283f0 100644 --- a/FirebaseTwitterAuthUI/FUITwitterAuth.m +++ b/FirebaseTwitterAuthUI/FUITwitterAuth.m @@ -87,6 +87,14 @@ - (UIColor *)buttonTextColor { - (void)signInWithEmail:(nullable NSString *)email presentingViewController:(nullable UIViewController *)presentingViewController completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { + [self signInWithDefaultValue:email + presentingViewController:presentingViewController + completion:completion]; +} + +- (void)signInWithDefaultValue:(nullable NSString *)defaultValue + presentingViewController:(nullable UIViewController *)presentingViewController + completion:(nullable FIRAuthProviderSignInCompletionBlock)completion { [[self getTwitterManager] logInWithViewController:presentingViewController completion:^(TWTRSession *_Nullable session, diff --git a/FirebaseUI.xcodeproj/project.pbxproj b/FirebaseUI.xcodeproj/project.pbxproj index 3326b2678b0..a8c85baa315 100644 --- a/FirebaseUI.xcodeproj/project.pbxproj +++ b/FirebaseUI.xcodeproj/project.pbxproj @@ -129,6 +129,9 @@ 8DFA90471DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 8DFA90451DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8DFA90481DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DFA90461DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.m */; }; 8DFA90491DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DFA90461DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.m */; }; + C310EB001F67524400666879 /* FUIPhoneNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = C310EAFE1F67524400666879 /* FUIPhoneNumber.h */; }; + C310EB011F67524400666879 /* FUIPhoneNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = C310EAFF1F67524400666879 /* FUIPhoneNumber.m */; }; + C310EB021F67524400666879 /* FUIPhoneNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = C310EAFF1F67524400666879 /* FUIPhoneNumber.m */; }; C3204F0C1E98340400841149 /* FUICountryTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C3204F0B1E98340400841149 /* FUICountryTableViewController.xib */; }; C32516951D88A54C00B0B3F9 /* FirebaseTwitterAuthUI.h in Headers */ = {isa = PBXBuildFile; fileRef = C32516941D88A54C00B0B3F9 /* FirebaseTwitterAuthUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; C32516A11D88A54C00B0B3F9 /* FirebaseTwitterAuthUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = C32516A01D88A54C00B0B3F9 /* FirebaseTwitterAuthUITests.m */; }; @@ -586,6 +589,8 @@ 8DFA90411DAC1DAC003B5E10 /* FUIIndexTableViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUIIndexTableViewDataSource.m; sourceTree = ""; }; 8DFA90451DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUIIndexCollectionViewDataSource.h; sourceTree = ""; }; 8DFA90461DAC54DD003B5E10 /* FUIIndexCollectionViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUIIndexCollectionViewDataSource.m; sourceTree = ""; }; + C310EAFE1F67524400666879 /* FUIPhoneNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUIPhoneNumber.h; sourceTree = ""; }; + C310EAFF1F67524400666879 /* FUIPhoneNumber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUIPhoneNumber.m; sourceTree = ""; }; C3204F0B1E98340400841149 /* FUICountryTableViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FUICountryTableViewController.xib; sourceTree = ""; }; C32516921D88A54C00B0B3F9 /* FirebaseTwitterAuthUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FirebaseTwitterAuthUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C32516941D88A54C00B0B3F9 /* FirebaseTwitterAuthUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirebaseTwitterAuthUI.h; sourceTree = ""; }; @@ -1834,6 +1839,8 @@ C3204F0B1E98340400841149 /* FUICountryTableViewController.xib */, C3A08D971E97227A00FF63EB /* FUIFeatureSwitch.h */, C3A08D981E97227A00FF63EB /* FUIFeatureSwitch.m */, + C310EAFE1F67524400666879 /* FUIPhoneNumber.h */, + C310EAFF1F67524400666879 /* FUIPhoneNumber.m */, ); path = CountryCode; sourceTree = ""; @@ -1981,6 +1988,7 @@ C3A08D9C1E97227A00FF63EB /* FUICountryCodes.h in Headers */, C3A2017A1E9597DA0040563F /* FUIPhoneVerificationViewController.h in Headers */, C3773B851E92C3CF00ACF58C /* FUIPhoneAuth.h in Headers */, + C310EB001F67524400666879 /* FUIPhoneNumber.h in Headers */, C3A201771E9597DA0040563F /* FUIPhoneEntryViewController.h in Headers */, C37296841E95C83900F3FCCC /* FUICodeField.h in Headers */, C343D29B1E96ADD400DD9C61 /* FUIPhoneAuth_Internal.h in Headers */, @@ -3074,6 +3082,7 @@ C3A08DA01E97227A00FF63EB /* FUICountryTableViewController.m in Sources */, C3773B861E92C3CF00ACF58C /* FUIPhoneAuth.m in Sources */, C3A2017B1E9597DA0040563F /* FUIPhoneVerificationViewController.m in Sources */, + C310EB011F67524400666879 /* FUIPhoneNumber.m in Sources */, C3A201781E9597DA0040563F /* FUIPhoneEntryViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3082,6 +3091,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C310EB021F67524400666879 /* FUIPhoneNumber.m in Sources */, C3773B641E8EFDEB00ACF58C /* FirebasePhoneAuthUITests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m b/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m index c9eec253c52..fd15ff3eebf 100644 --- a/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m +++ b/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m @@ -194,7 +194,7 @@ - (IBAction)onAuthorization:(id)sender { self.authUI.isSignInWithEmailHidden; if (shouldSkipPhoneAuthPicker) { FUIPhoneAuth *provider = self.authUI.providers.firstObject; - [provider signInWithPresentingViewController:self]; + [provider signInWithPresentingViewController:self phoneNumber:nil]; } else { UINavigationController *controller = [self.authUI authViewController]; if (_isCustomAuthDelegateSelected) { diff --git a/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUICustomPasswordSignInViewController.m b/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUICustomPasswordSignInViewController.m index e24461ca02e..077ea241ea5 100644 --- a/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUICustomPasswordSignInViewController.m +++ b/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUICustomPasswordSignInViewController.m @@ -59,7 +59,7 @@ - (IBAction)onForgotPasswordPressed:(id)sender { } - (IBAction)onNextPressed:(id)sender { - [self signInWithEmail:_emailTextField.text andPassword:_passwordTextField.text]; + [self signInWithDefaultValue:_emailTextField.text andPassword:_passwordTextField.text]; } - (IBAction)onCancelPressed:(id)sender {