import SwiftUI import AuthenticationServices import CryptoKit /// 自定义的 Apple 登录按钮组件 struct AppleSignInButton: View { // MARK: - 属性 /// 授权请求回调 let onRequest: (ASAuthorizationAppleIDRequest) -> Void /// 授权完成回调 let onCompletion: (Result) -> Void /// 按钮文字 let buttonText: String // MARK: - 初始化方法 init(buttonText: String = "Continue with Apple", onRequest: @escaping (ASAuthorizationAppleIDRequest) -> Void, onCompletion: @escaping (Result) -> Void) { self.buttonText = buttonText self.onRequest = onRequest self.onCompletion = onCompletion } // MARK: - 视图主体 var body: some View { Button(action: handleSignIn) { HStack(alignment: .center, spacing: 8) { Image(systemName: "applelogo") .font(.system(size: 20, weight: .regular)) Text(buttonText) .font(.system(size: 18, weight: .regular)) } .frame(maxWidth: .infinity) .frame(height: 60) .background(Color.white) .foregroundColor(.black) .cornerRadius(30) .overlay( RoundedRectangle(cornerRadius: 30) .stroke(Color.black, lineWidth: 1) // 使用黑色边框 ) } } // MARK: - 私有方法 private func handleSignIn() { let provider = ASAuthorizationAppleIDProvider() let request = provider.createRequest() request.requestedScopes = [.fullName, .email] // 创建 nonce 用于安全验证 let nonce = String.randomURLSafeString(length: 32) request.nonce = sha256(nonce) // 调用请求回调 onRequest(request) // 创建并显示授权控制器 let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = Coordinator(onCompletion: onCompletion) controller.performRequests() } private func sha256(_ input: String) -> String { let inputData = Data(input.utf8) let hashedData = SHA256.hash(data: inputData) return hashedData.compactMap { String(format: "%02x", $0) }.joined() } // MARK: - 协调器 private class Coordinator: NSObject, ASAuthorizationControllerDelegate { let onCompletion: (Result) -> Void init(onCompletion: @escaping (Result) -> Void) { self.onCompletion = onCompletion } // 授权成功回调 func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { onCompletion(.success(authorization)) } // 授权失败回调 func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { onCompletion(.failure(error)) } } }