SwiftUI中如何在SignInWithAppleButton启动授权前校验条款同意状态
解决SwiftUI中Apple登录前校验服务条款的方案
核心思路
通过手动触发Apple授权流程替代SignInWithAppleButton的默认点击逻辑,先完成条款勾选校验,再启动登录流程,避免用户先走完Apple授权才收到提示。
具体实现步骤
- 导入依赖框架
import AuthenticationServices import SwiftUI
- 定义视图状态变量
struct RegistrationView: View { @State private var isTermsAccepted = false @State private var showTermsAlert = false var body: some View { // 注册界面内容... } }
- 构建带前置校验的Apple登录按钮
用ZStack将视觉展示的SignInWithAppleButton与透明点击按钮叠加,透明按钮负责校验逻辑,通过后手动发起授权:
ZStack { // 仅作为视觉展示的Apple登录按钮,不绑定默认点击逻辑 SignInWithAppleButton(.signUp) { _ in } onCompletion: { _ in } .frame(height: 50) .cornerRadius(8) // 透明按钮处理点击校验 Button(action: { // 前置校验:检查条款是否勾选 guard isTermsAccepted else { showTermsAlert = true return } // 校验通过,手动发起Apple授权流程 let provider = ASAuthorizationAppleIDProvider() let request = provider.createRequest() request.requestedScopes = [.fullName, .email] // 按需配置权限 let authController = ASAuthorizationController(authorizationRequests: [request]) authController.delegate = self authController.presentationContextProvider = self authController.performRequests() }) { Color.clear .frame(height: 50) .cornerRadius(8) } } .alert("请先同意服务条款", isPresented: $showTermsAlert) { Button("确定", role: .cancel) {} }
- 实现授权代理方法
让视图遵守ASAuthorizationControllerDelegate和ASAuthorizationControllerPresentationContextProviding协议,处理授权结果:
extension RegistrationView: ASAuthorizationControllerDelegate { func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { // 处理授权成功逻辑,与原onCompletion回调逻辑一致 if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential { let userID = appleIDCredential.user let fullName = appleIDCredential.fullName let email = appleIDCredential.email // 后续注册流程... } } func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { // 处理授权失败逻辑 print("Apple登录失败:\(error.localizedDescription)") } } extension RegistrationView: ASAuthorizationControllerPresentationContextProviding { func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { // 获取当前展示窗口 guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, let mainWindow = windowScene.windows.first else { return ASPresentationAnchor() } return mainWindow } }
方案优势
- 完全在Apple授权流程启动前完成条款校验,避免无效授权操作
- 保留官方
SignInWithAppleButton的原生视觉样式 - 逻辑清晰,无需修改原有授权成功后的业务代码
内容的提问来源于stack exchange,提问作者Andrea Olivato
相关产品推荐
相关产品推荐

