macOS 12.4下ASWebAuthenticationSession无响应问题如何解决
macOS 12.4下ASWebAuthenticationSession弹窗按钮无响应问题
问题现象
应用中使用ASWebAuthenticationSession实现授权功能,macOS 12.4之前系统版本运行正常,升级至macOS 12.4后出现无响应问题:日志打印session.start success即会话启动成功后,点击弹窗的「取消」或「继续」按钮均无任何反应。

原有问题实现代码:
var session = ASWebAuthenticationSession.init(url: url, callbackURLScheme: "http", completionHandler: completionHandler) guard let provider = NSApplication.shared.keyWindow!.contentViewController as? FlutterViewController else { result(FlutterError(code: "FAILED", message: "Failed to aquire root FlutterViewController" , details: nil)) return } session.presentationContextProvider = provider if(!session.start()) { NSLog("session.start fail"); } else { NSLog("session.start success"); }
故障原因
- 核心问题是
ASWebAuthenticationSession实例被定义为函数内局部变量,函数执行结束后ARC机制会在引用计数归零时释放该实例。macOS 12.4之前的系统版本会在start()调用后由系统框架内部临时持有session实例,保障交互过程中对象不被回收;12.4版本修改了对象持有逻辑,不再替业务侧持有实例,对象提前释放后,弹窗的所有点击事件找不到响应目标,自然无反应。 - 额外校验点:作为
presentationContextProvider传入的控制器需实现ASWebAuthenticationPresentationContextProviding协议,正确返回展示锚点窗口,否则也可能出现弹窗层级异常导致交互失效。
修复方案
- 将
ASWebAuthenticationSession实例改为当前类/插件的强引用成员属性,不要使用函数局部变量,保证授权流程全周期对象不被释放。 - 确认传入的
presentationContextProvider正确实现了协议方法,返回可用的展示窗口。 - 授权流程结束(成功/取消/报错)后,再手动将session属性置空释放资源。
修复后参考代码:
// 首先在当前类/插件的属性声明区添加强引用属性 var authSession: ASWebAuthenticationSession? // 原有授权逻辑修改为 authSession = ASWebAuthenticationSession( url: url, callbackURLScheme: "http" ) { [weak self] callbackURL, error in // 回调执行完成后释放session实例 defer { self?.authSession = nil } // 原有授权结果处理逻辑 completionHandler(callbackURL, error) } guard let provider = NSApplication.shared.keyWindow?.contentViewController as? FlutterViewController else { result(FlutterError(code: "FAILED", message: "Failed to aquire root FlutterViewController" , details: nil)) return } // 需确保FlutterViewController实现ASWebAuthenticationPresentationContextProviding协议,参考实现: // extension FlutterViewController: ASWebAuthenticationPresentationContextProviding { // func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { // return self.view.window ?? ASPresentationAnchor() // } // } authSession?.presentationContextProvider = provider guard let isStartSuccess = authSession?.start(), isStartSuccess else { NSLog("session.start fail") return } NSLog("session.start success")
内容的提问来源于stack exchange,提问作者Mars Cai
相关产品推荐
相关产品推荐

