You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 19:08:22