ASWebAuthenticationSession登录按钮无响应问题求助
解决ASWebAuthenticationSession无响应的问题
以下是针对你的代码问题的具体修复思路和代码调整方案:
1. 修复Presentation Anchor的获取逻辑
当前代码返回的是全新创建的ASPresentationAnchor(),这不是应用的有效窗口,系统无法展示认证页面。需要获取当前应用的活跃主窗口:
extension WebAuthenticate: ASWebAuthenticationPresentationContextProviding { func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { // 获取当前活跃的主窗口 guard let window = UIApplication.shared.connectedScenes .filter({ $0.activationState == .foregroundActive }) .compactMap({ $0 as? UIWindowScene }) .first?.windows .first(where: { $0.isKeyWindow }) else { return ASPresentationAnchor() } return window } }
2. 持有Session实例避免提前释放
原代码中ASWebAuthenticationSession是方法内的局部变量,方法执行完毕后会被立即销毁,导致会话无法启动。需要将其定义为类的属性:
class WebAuthenticate: NSObject, ObservableObject { // 持有session实例,延长生命周期 private var authSession: ASWebAuthenticationSession? @Published var isAuthenticated = false // 用于通知视图更新认证状态 func authenticate() { // 补充eBay OAuth必填参数:替换YOUR_CLIENT_ID为你的开发者ID,scope/redirect_uri需与平台配置一致 guard let authURL = URL(string: "https://auth.sandbox.ebay.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=myapp://callback&scope=https://api.ebay.com/oauth/api_scope") else { return } let scheme = "myapp" authSession = ASWebAuthenticationSession(url: authURL, callbackURLScheme: scheme) { [weak self] callbackURL, error in defer { self?.authSession = nil } // 回调结束后释放session if let error = error { print("认证错误:\(error.localizedDescription)") return } if let callbackURL = callbackURL { // 解析回调中的授权码,后续可用于获取access token let code = URLComponents(url: callbackURL, resolvingAgainstBaseURL: false)? .queryItems?.first(where: { $0.name == "code" })?.value print("获取到授权码:\(code ?? "")") self?.isAuthenticated = true // 更新认证状态 } } authSession?.presentationContextProvider = self authSession?.start() } func logout() { isAuthenticated = false // 可添加清除token、重置状态的逻辑 } }
3. 配置自定义URL Scheme
在项目的Info.plist中添加自定义Scheme(myapp),确保系统能回调到你的应用:
右键Info.plist → 选择Open As → Source Code,添加以下内容:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> </array>
4. 简化视图状态管理
直接使用WebAuthenticate中的isAuthenticated状态,无需视图自行维护:
struct LoginView: View { @StateObject private var auth = WebAuthenticate() var body: some View { VStack { Text("Welcome, please login") .padding(100) Spacer() if auth.isAuthenticated { VStack { Text("You’re logged in!") Button("Log out") { auth.logout() } } } else { Button("Log in") { auth.authenticate() } } } } }
内容的提问来源于stack exchange,提问作者Electronic Trip
相关产品推荐
相关产品推荐

