Возможность подписи с Apple включена в обеих версиях Debug (Нет в качестве команды) и Версия (с личной командой)
введите здесь описание изображения
Это код для кнопки «Войти с помощью Apple»
Код: Выделить всё
SignInWithAppleButton { request in
viewModel.handleSignInWithAppleRequest(request)
} onCompletion: { result in
viewModel.handleSignInWithAppleCompletion(result)
//print("check this out: \(result)")
switch result {
case .success(let authResult):
print("Authentication success: \(authResult)")
// If the sign-in was successful, set isShowing to false to dismiss the sign-in view
isShowing = false
case .failure(let error):
print("Authentication failed with error: \(error)")
// Optionally handle errors or update UI accordingly
}
}
Код: Выделить всё
extension AuthenticationViewModel {
func handleSignInWithAppleRequest(_ request: ASAuthorizationAppleIDRequest) {
request.requestedScopes = [.fullName, .email] // apple is particular about requesting User details, if we dont need we can skip it
let nonce = randomNonceString() // nonce is a random number used to prevent replay attacks
currentNonce = nonce
request.nonce = sha256(nonce) // output of sha256 is always 256 bits aka hash function
}
func handleSignInWithAppleCompletion(_ result: Result) {
if case .failure(let failure) = result {
errorMessage = failure.localizedDescription
}
else if case .success(let success) = result {
if let appleIDCredential = success.credential as? ASAuthorizationAppleIDCredential {
guard let nonce = currentNonce else {
fatalError("Invalid State: a login callback was received")
}
guard let appleIDToken = appleIDCredential.identityToken else{
print("Unable to fetch identity token")
return
}
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
print("unable to serialize token string from data: \(appleIDToken.debugDescription)")
return
}
// let credential = OAuthProvider.appleCredential(//withProviderID: "apple.com",
// withIDToken: idTokenString,
// rawNonce: nonce,
// fullName: appleIDCredential.fullName)
let credential = OAuthProvider.credential(withProviderID: "apple.com",
idToken: idTokenString,
rawNonce: nonce)
//'credential(withProviderID:idToken:rawNonce:)' is deprecated: Use credential(providerID: AuthProviderID, idToken: String, rawNonce: String, accessToken: String? = nil) -> OAuthCredential instead.
//https://stackoverflow.com/questions/77078754/i-cant-log-in-by-following-the-guide-from-firebase
Task {
do {
let result = try await Auth.auth().signIn(with: credential)
await updateDisplayName(for: result.user, with: appleIDCredential)
} catch {
print("Error authenticating: \(error.localizedDescription)")
}
}
}
}
}
func updateDisplayName(for user: User, with appleIDCredential: ASAuthorizationAppleIDCredential, force: Bool = false) async {
if let currentDisplayName = Auth.auth().currentUser?.displayName, currentDisplayName.isEmpty {
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = appleIDCredential.displayName()
do {
try await changeRequest.commitChanges()
self.displayName = Auth.auth().currentUser?.displayName ?? ""
}
catch {
print("Unable to update the user's displayname: \(error.localizedDescription)")
errorMessage = error.localizedDescription
}
}
}
func verifySignInWithAppleAuthenticationState() {
let appleIDProvider = ASAuthorizationAppleIDProvider()
let providerData = Auth.auth().currentUser?.providerData
if let appleProviderData = providerData?.first(where: { $0.providerID == "apple.com" }) {
Task {
do {
let credentialState = try await appleIDProvider.credentialState(forUserID: appleProviderData.uid)
switch credentialState {
case .authorized:
break // The Apple ID credential is valid.
case .revoked, .notFound:
// The Apple ID credential is either revoked or was not found, so show the sign-in UI.
self.signOut()
default:
break
}
}
catch {
}
}
}
}
}
extension ASAuthorizationAppleIDCredential {
func displayName() -> String {
return [self.fullName?.givenName, self.fullName?.familyName]
.compactMap( {$0})
.joined(separator: " ")
}
}
// Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
private func randomNonceString(length: Int = 32) -> String {
precondition(length > 0)
let charset: [Character] =
Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
var result = ""
var remainingLength = length
while remainingLength > 0 {
let randoms: [UInt8] = (0 ..< 16).map { _ in
var random: UInt8 = 0
let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
if errorCode != errSecSuccess {
fatalError(
"Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)"
)
}
return random
}
randoms.forEach { random in
if remainingLength == 0 {
return
}
if random < charset.count {
result.append(charset[Int(random)])
remainingLength -= 1
}
}
}
return result
}
private func sha256(_ input: String) -> String {
let inputData = Data(input.utf8)
let hashedData = SHA256.hash(data: inputData)
let hashString = hashedData.compactMap {
String(format: "%02x", $0)
}.joined()
return hashString
}
Я пробовал удалить и добавить возможность «Подписание с Apple», как упоминалось во многих статьях
Не удалось включить «Вход с Apple» в Xcode
но это не сработало либо
Подробнее здесь: https://stackoverflow.com/questions/790 ... -via-apple
Мобильная версия