@@ -156,6 +156,32 @@ final class ViewController: UIViewController, UITextFieldDelegate {
156
156
view. endEditing ( true )
157
157
}
158
158
159
+ func verify( phoneNumber: String , completion: @escaping ( PhoneAuthCredential ? , Error ? ) -> Void ) {
160
+ if #available( iOS 8 . 0 , * ) {
161
+ PhoneAuthProvider . provider ( ) . verifyPhoneNumber ( phoneNumber) { verificationID, error in
162
+ guard error == nil else {
163
+ completion ( nil , error)
164
+ return
165
+ }
166
+ let codeAlertController =
167
+ UIAlertController ( title: " Enter Code " , message: nil , preferredStyle: . alert)
168
+ codeAlertController. addTextField { textfield in
169
+ textfield. placeholder = " SMS Code "
170
+ textfield. keyboardType = UIKeyboardType . numberPad
171
+ }
172
+ codeAlertController. addAction ( UIAlertAction ( title: " OK " ,
173
+ style: . default,
174
+ handler: { ( UIAlertAction) in
175
+ let code = codeAlertController. textFields!. first!. text!
176
+ let phoneCredential =
177
+ PhoneAuthProvider . provider ( ) . credential ( withVerificationID: verificationID ?? " " ,
178
+ verificationCode: code)
179
+ completion ( phoneCredential, nil )
180
+ } ) )
181
+ self . present ( codeAlertController, animated: true , completion: nil )
182
+ }
183
+ }
184
+ }
159
185
/// The user's photo URL used by the last network request for its contents.
160
186
fileprivate var lastPhotoURL : URL ? = nil
161
187
@@ -221,6 +247,20 @@ final class ViewController: UIViewController, UITextFieldDelegate {
221
247
self . showAlert ( title: " Updated Email " , message: self . user? . email)
222
248
}
223
249
}
250
+ case . updatePhone:
251
+ let phoneNumber = phoneField. text
252
+ self . verify ( phoneNumber: phoneNumber!, completion: { ( phoneAuthCredential, error) in
253
+ guard error == nil else {
254
+ self . showAlert ( title: " Error " , message: error!. localizedDescription)
255
+ return
256
+ }
257
+ self . user!. updatePhoneNumber ( phoneAuthCredential!, completion: { error in
258
+ self . ifNoError ( error) {
259
+ self . showAlert ( title: " Updated Phone Number " )
260
+ self . updateUserInfo ( Auth . auth ( ) )
261
+ }
262
+ } )
263
+ } )
224
264
case . updatePassword:
225
265
user!. updatePassword ( to: passwordField. text!) { error in
226
266
self . ifNoError ( error) {
@@ -281,32 +321,14 @@ final class ViewController: UIViewController, UITextFieldDelegate {
281
321
completion ( EmailAuthProvider . credential ( withEmail: emailField. text!,
282
322
password: passwordField. text!) )
283
323
case . phone:
284
- if #available( iOS 8 . 0 , * ) {
285
- let phoneNumber = phoneField. text
286
- PhoneAuthProvider . provider ( ) . verifyPhoneNumber ( phoneNumber!) { verificationID, error in
287
- guard error == nil else {
288
- self . showAlert ( title: " Error " , message: error!. localizedDescription)
289
- return
290
- }
291
-
292
- let codeAlertController =
293
- UIAlertController ( title: " Enter Code " , message: nil , preferredStyle: . alert)
294
- codeAlertController. addTextField { ( textfield) in
295
- textfield. placeholder = " SMS Codde "
296
- textfield. keyboardType = UIKeyboardType . numberPad
297
- }
298
- codeAlertController. addAction ( UIAlertAction ( title: " OK " ,
299
- style: . default,
300
- handler: { ( UIAlertAction) in
301
- let code = codeAlertController. textFields!. first!. text!
302
- let phoneCredential =
303
- PhoneAuthProvider . provider ( ) . credential ( withVerificationID: verificationID ?? " " ,
304
- verificationCode: code)
305
- completion ( phoneCredential)
306
- } ) )
307
- self . present ( codeAlertController, animated: true , completion: nil )
324
+ let phoneNumber = phoneField. text
325
+ self . verify ( phoneNumber: phoneNumber!, completion: { ( phoneAuthCredential, error) in
326
+ guard error == nil else {
327
+ self . showAlert ( title: " Error " , message: error!. localizedDescription)
328
+ return
308
329
}
309
- }
330
+ completion ( phoneAuthCredential!)
331
+ } )
310
332
}
311
333
}
312
334
@@ -356,7 +378,7 @@ final class ViewController: UIViewController, UITextFieldDelegate {
356
378
action. requiresPassword
357
379
passwordInputLabel. alpha = isPasswordEnabled ? 1.0 : 0.6
358
380
passwordField. isEnabled = isPasswordEnabled
359
- phoneField. isEnabled = credentialType. requiresPhone
381
+ phoneField. isEnabled = credentialType. requiresPhone || action . requiresPhoneNumber
360
382
}
361
383
362
384
fileprivate func showAlert( title: String , message: String ? = " " ) {
@@ -499,14 +521,17 @@ fileprivate protocol Action {
499
521
/// The text description for the particular action.
500
522
var text : String { get }
501
523
502
- /// Whether or not the action requires credential.
524
+ /// Whether or not the action requires a credential.
503
525
var requiresCredential : Bool { get }
504
526
505
- /// Whether or not the action requires email.
527
+ /// Whether or not the action requires an email.
506
528
var requiresEmail : Bool { get }
507
529
508
- /// Whether or not the credential requires password.
530
+ /// Whether or not the credential requires a password.
509
531
var requiresPassword : Bool { get }
532
+
533
+ /// Whether or not the credential requires a phone number.
534
+ var requiresPhoneNumber : Bool { get }
510
535
}
511
536
512
537
/// The list of all possible actions the operator can take on the Auth object.
@@ -545,13 +570,17 @@ fileprivate enum AuthAction: Int, Action {
545
570
var requiresPassword : Bool {
546
571
return self == . createUser
547
572
}
573
+
574
+ var requiresPhoneNumber : Bool {
575
+ return false
576
+ }
548
577
}
549
578
550
579
/// The list of all possible actions the operator can take on the User object.
551
580
fileprivate enum UserAction : Int , Action {
552
581
553
- case updateEmail, updatePassword, reload, reauthenticate, getToken, linkWithCredential ,
554
- deleteAccount
582
+ case updateEmail, updatePhone , updatePassword, reload, reauthenticate, getToken,
583
+ linkWithCredential , deleteAccount
555
584
556
585
/// Total number of user actions.
557
586
static var count : Int {
@@ -562,6 +591,12 @@ fileprivate enum UserAction: Int, Action {
562
591
switch self {
563
592
case . updateEmail:
564
593
return " Update Email ⬇️ "
594
+ case . updatePhone:
595
+ if #available( iOS 8 . 0 , * ) {
596
+ return " Update Phone ⬇️ "
597
+ } else {
598
+ return " - "
599
+ }
565
600
case . updatePassword:
566
601
return " Update Password ⬇️ "
567
602
case . reload:
@@ -588,6 +623,11 @@ fileprivate enum UserAction: Int, Action {
588
623
var requiresPassword : Bool {
589
624
return self == . updatePassword
590
625
}
626
+
627
+ var requiresPhoneNumber : Bool {
628
+ return self == . updatePhone
629
+ }
630
+
591
631
}
592
632
593
633
/// The list of all possible credential types the operator can use to sign in or link.
@@ -616,17 +656,17 @@ fileprivate enum CredentialType: Int {
616
656
}
617
657
}
618
658
619
- /// Whether or not the credential requires email.
659
+ /// Whether or not the credential requires an email.
620
660
var requiresEmail : Bool {
621
661
return self == . password
622
662
}
623
663
624
- /// Whether or not the credential requires password.
664
+ /// Whether or not the credential requires a password.
625
665
var requiresPassword : Bool {
626
666
return self == . password
627
667
}
628
668
629
- /// Whether or not the credential requires phone.
669
+ /// Whether or not the credential requires a phone number .
630
670
var requiresPhone : Bool {
631
671
return self == . phone
632
672
}
0 commit comments