SwiftUI中SignInWithAppleButton带onRequest参数调用报错如何解决?
报错原因
带onRequest和onCompletion参数的构造器是系统AuthenticationServices框架中SwiftUI版SignInWithAppleButton的标准构造器,本身功能正常,出现该报错的核心原因是当前代码调用的SignInWithAppleButton不是系统提供的正确类型:
- 未在当前Swift文件顶部导入
AuthenticationServices框架,编译器识别不到带参构造器 - 项目中存在自定义的同名
SignInWithAppleButton类型,或是引入的第三方库包含同名类型,覆盖了系统类型 - 项目最低部署版本低于iOS 14.0 / macOS 11.0 / tvOS 14.0 / watchOS 7.0,系统自带的SwiftUI版
SignInWithAppleButton在这些版本以下不可用,编译器会自动匹配到其他同名无参类型 - 从Xcode控件库拖拽控件时,Xcode没有自动导入依赖框架,仅生成了无参的占位控件代码
解决方案
方案1:优先使用官方标准构造器
如果你的项目最低支持版本符合要求,按以下步骤修正即可正常使用带参写法:
- 确认当前文件顶部已添加依赖导入:
import SwiftUI import AuthenticationServices
- 为避免重名冲突,可显式指定调用系统框架的控件:
AuthenticationServices.SignInWithAppleButton( onRequest: { request in // 配置请求参数,示例:请求邮箱、全名权限 request.requestedScopes = [.fullName, .email] }, onCompletion: { result in // 处理授权结果 switch result { case .success(let authorization): // 授权成功逻辑 case .failure(let error): // 授权失败逻辑 } } ) .frame(height: 50) .padding()
方案2:无参构造器替代/低版本兼容写法
如果需要兼容iOS 13及以下版本,或是确定要使用无参构造器,可以通过onTapGesture配合ASAuthorizationAppleIDProvider实现完全相同的功能:
import SwiftUI import AuthenticationServices struct LoginView: View { var body: some View { SignInWithAppleButton() .frame(height: 50) .onTapGesture { handleAppleSignIn() } .padding() } private func handleAppleSignIn() { let provider = ASAuthorizationAppleIDProvider() let request = provider.createRequest() request.requestedScopes = [.fullName, .email] let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = AuthDelegate() controller.presentationContextProvider = AuthPresentationProvider() controller.performRequests() } } // 单独封装授权结果回调代理 class AuthDelegate: NSObject, ASAuthorizationControllerDelegate { func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { // 授权成功逻辑 } func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { // 授权失败逻辑 } } // 单独封装授权弹窗提供逻辑 class AuthPresentationProvider: NSObject, ASAuthorizationControllerPresentationContextProviding { func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { UIApplication.shared.connectedScenes .filter { $0.activationState == .foregroundActive } .compactMap { $0 as? UIWindowScene } .first?.windows .filter { $0.isKeyWindow } .first ?? UIWindow() } }
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

