@@ -191,6 +191,18 @@ class AuthViewController: UIViewController, DataSourceProviderDelegate {
191
191
192
192
case . multifactorUnenroll:
193
193
mfaUnenroll ( )
194
+
195
+ case . passkeySignUp:
196
+ passkeySignUp ( )
197
+
198
+ case . passkeyEnroll:
199
+ Task { await passkeyEnroll ( ) }
200
+
201
+ case . passkeySignIn:
202
+ Task { await passkeySignIn ( ) }
203
+
204
+ case . passkeyUnenroll:
205
+ Task { await passkeyUnenroll ( ) }
194
206
}
195
207
}
196
208
@@ -922,6 +934,87 @@ class AuthViewController: UIViewController, DataSourceProviderDelegate {
922
934
}
923
935
}
924
936
937
+ // MARK: - Passkey
938
+
939
+ private func passkeySignUp( ) {
940
+ guard #available( iOS 16 . 0 , macOS 12 . 0 , tvOS 16 . 0 , * ) else {
941
+ print ( " OS version is not supported for this action. " )
942
+ return
943
+ }
944
+ Task {
945
+ do {
946
+ _ = try await AppManager . shared. auth ( ) . signInAnonymously ( )
947
+ print ( " sign-in anonymously succeeded. " )
948
+ if let uid = AppManager . shared. auth ( ) . currentUser? . uid {
949
+ print ( " User ID: \( uid) " )
950
+ }
951
+ // Continue to enroll a passkey.
952
+ await passkeyEnroll ( )
953
+ } catch {
954
+ print ( " sign-in anonymously failed: \( error. localizedDescription) " )
955
+ self . showAlert ( for: " Anonymous Sign-In Failed " )
956
+ }
957
+ }
958
+ }
959
+
960
+ private func passkeyEnroll( ) async {
961
+ guard let user = AppManager . shared. auth ( ) . currentUser else {
962
+ showAlert ( for: " Please sign in first. " )
963
+ return
964
+ }
965
+ let passkeyName = await showTextInputPrompt ( with: " Passkey name " )
966
+ guard #available( iOS 16 . 0 , macOS 12 . 0 , tvOS 16 . 0 , * ) else {
967
+ showAlert ( for: " Not Supported " , message: " This OS version does not support passkeys. " )
968
+ return
969
+ }
970
+
971
+ do {
972
+ let request = try await user. startPasskeyEnrollment ( withName: passkeyName)
973
+ let controller = ASAuthorizationController ( authorizationRequests: [ request] )
974
+ controller. delegate = self
975
+ controller. presentationContextProvider = self
976
+ controller. performRequests ( )
977
+ print ( " Started passkey enrollment (challenge created). " )
978
+ } catch {
979
+ showAlert ( for: " Passkey enrollment failed " , message: error. localizedDescription)
980
+ print ( " startPasskeyEnrollment failed: \( error. localizedDescription) " )
981
+ }
982
+ }
983
+
984
+ private func passkeySignIn( ) async {
985
+ guard #available( iOS 16 . 0 , macOS 12 . 0 , tvOS 16 . 0 , * ) else {
986
+ print ( " OS version is not supported for this action. " )
987
+ return
988
+ }
989
+ do {
990
+ let request = try await AppManager . shared. auth ( ) . startPasskeySignIn ( )
991
+ let controller = ASAuthorizationController ( authorizationRequests: [ request] )
992
+ controller. delegate = self
993
+ controller. presentationContextProvider = self
994
+ controller. performRequests ( )
995
+ print ( " Started passkey sign in (challenge created). " )
996
+ } catch {
997
+ print ( " Passkey sign-in failed with error: \( error) " )
998
+ }
999
+ }
1000
+
1001
+ private func passkeyUnenroll( ) async {
1002
+ guard let user = AppManager . shared. auth ( ) . currentUser else {
1003
+ showAlert ( for: " Please sign in first. " )
1004
+ return
1005
+ }
1006
+ guard let credentialId = await showTextInputPrompt ( with: " Credential Id " ) else {
1007
+ print ( " Passkey unenrollment cancelled: no credential id entered. " )
1008
+ return
1009
+ }
1010
+ do {
1011
+ let _ = try await user. unenrollPasskey ( withCredentialID: credentialId)
1012
+ } catch {
1013
+ showAlert ( for: " Passkey unenrollment failed " , message: error. localizedDescription)
1014
+ print ( " unenrollPasskey failed: \( error. localizedDescription) " )
1015
+ }
1016
+ }
1017
+
925
1018
// MARK: - Private Helpers
926
1019
927
1020
private func showTextInputPrompt( with message: String , completion: ( ( String ) -> Void ) ? = nil ) {
@@ -1027,6 +1120,43 @@ extension AuthViewController: ASAuthorizationControllerDelegate,
1027
1120
1028
1121
func authorizationController( controller: ASAuthorizationController ,
1029
1122
didCompleteWithAuthorization authorization: ASAuthorization ) {
1123
+ if #available( iOS 16 . 0 , macOS 12 . 0 , tvOS 16 . 0 , * ) ,
1124
+ let regCred = authorization. credential
1125
+ as? ASAuthorizationPlatformPublicKeyCredentialRegistration {
1126
+ Task { @MainActor [ weak self] in
1127
+ guard let self else { return }
1128
+ do {
1129
+ guard let user = AppManager . shared. auth ( ) . currentUser else {
1130
+ self . showAlert ( for: " Finalize failed " , message: " No signed-in user. " )
1131
+ return
1132
+ }
1133
+ _ = try await user. finalizePasskeyEnrollment ( withPlatformCredential: regCred)
1134
+ self . showAlert ( for: " Passkey Enrollment " , message: " Succeeded " )
1135
+ print ( " Passkey Enrollment succeeded. " )
1136
+ } catch {
1137
+ self . showAlert ( for: " Passkey Enrollment failed " , message: error. localizedDescription)
1138
+ print ( " Finalize enrollment failed: \( error. localizedDescription) " )
1139
+ }
1140
+ }
1141
+ return
1142
+ }
1143
+ if let assertion = authorization
1144
+ . credential as? ASAuthorizationPlatformPublicKeyCredentialAssertion {
1145
+ Task { @MainActor [ weak self] in
1146
+ guard let self else { return }
1147
+ do {
1148
+ let _ = try await AppManager . shared. auth ( )
1149
+ . finalizePasskeySignIn ( withPlatformCredential: assertion)
1150
+ self . showAlert ( for: " Passkey Sign-In " , message: " Succeeded " )
1151
+ print ( " Passkey sign-in succeeded. " )
1152
+ self . transitionToUserViewController ( )
1153
+ } catch {
1154
+ self . showAlert ( for: " Passkey Sign-In failed " , message: error. localizedDescription)
1155
+ print ( " Finalize passkey sign-in failed: \( error. localizedDescription) " )
1156
+ }
1157
+ }
1158
+ return
1159
+ }
1030
1160
guard let appleIDCredential = authorization. credential as? ASAuthorizationAppleIDCredential
1031
1161
else {
1032
1162
print ( " Unable to retrieve AppleIDCredential " )
@@ -1074,10 +1204,10 @@ extension AuthViewController: ASAuthorizationControllerDelegate,
1074
1204
1075
1205
func authorizationController( controller: ASAuthorizationController ,
1076
1206
didCompleteWithError error: any Error ) {
1077
- // Ensure that you have:
1207
+ print ( " Apple authorization failed: \( error) " )
1208
+ // for Sign In with Apple, ensure that you have:
1078
1209
// - enabled `Sign in with Apple` on the Firebase console
1079
1210
// - added the `Sign in with Apple` capability for this project
1080
- print ( " Sign in with Apple failed: \( error) " )
1081
1211
}
1082
1212
1083
1213
// MARK: ASAuthorizationControllerPresentationContextProviding
0 commit comments