Hello Apple Developer Community,
I'm experiencing an issue on macOS where ASWebAuthenticationSession fails to display its authentication window.
The session is created successfully and start() returns true, but:
- no UI is shown,
presentationAnchor(for:)is never invoked,- the completion handler is never called,
- and no errors appear in Console.app or Xcode logs.
This happens both when using the session via a Flutter plugin and when calling ASWebAuthenticationSession directly from Swift.
Environment
- macOS 14.6 (Sonoma)
- Xcode latest stable
- Target: macOS 10.15+
- App type: sandboxed macOS app, hardened runtime enabled
- The project also includes a Login Item (SMAppService) target
- Redirect URI scheme:
myapp-auth://callback
Problem Description
When I trigger authentication, the logs show:
[AuthPlugin] Starting ASWebAuthenticationSession...
After that:
- no authentication sheet appears,
presentationAnchor(for:)is never called,- the completion handler is not invoked.
The main window is visible and active when the method is called.
Swift Implementation
public class AuthPlugin: NSObject, FlutterPlugin, ASWebAuthenticationPresentationContextProviding {
private var webAuthSession: ASWebAuthenticationSession?
private var resultHandler: FlutterResult?
private func authenticate(url: URL, callbackScheme: String, result: @escaping FlutterResult) {
NSLog("[AuthPlugin] authenticate() called")
NSLog("[AuthPlugin] URL: %@", url.absoluteString)
NSLog("[AuthPlugin] Callback scheme: %@", callbackScheme)
resultHandler = result
let session = ASWebAuthenticationSession(
url: url,
callbackURLScheme: callbackScheme
) { [weak self] callbackURL, error in
NSLog("[AuthPlugin] completion handler invoked")
if let error = error {
NSLog("[AuthPlugin] error: %@", error.localizedDescription)
return
}
guard let callbackURL = callbackURL else {
NSLog("[AuthPlugin] missing callback URL")
return
}
self?.resultHandler?(callbackURL.absoluteString)
}
session.presentationContextProvider = self
session.prefersEphemeralWebBrowserSession = false
self.webAuthSession = session
NSLog("[AuthPlugin] Starting ASWebAuthenticationSession...")
let started = session.start()
NSLog("[AuthPlugin] start() returned: %@", started ? "true" : "false")
}
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
NSLog("[AuthPlugin] presentationAnchor called")
if let keyWindow = NSApplication.shared.windows.first(where: { $0.isKeyWindow }) {
NSLog("[AuthPlugin] using key window")
return keyWindow
}
if let firstWindow = NSApplication.shared.windows.first {
NSLog("[AuthPlugin] using first window")
return firstWindow
}
NSLog("[AuthPlugin] creating fallback window")
let window = NSWindow(
contentRect: .init(x: 0, y: 0, width: 400, height: 300),
styleMask: [.titled, .closable],
backing: .buffered,
defer: false
)
window.center()
window.makeKeyAndOrderFront(nil)
return window
}
}
Key Observations
- The session is created successfully.
- ASWebAuthenticationSession.start() returns true.
- presentationAnchor(for:) is never invoked.
- The completion handler is never triggered.
- No errors appear in system logs.
- The same code works correctly in a non-sandboxed macOS app.
- The main window is visible and the app is active when the session is started.
Questions
- What conditions must be met for macOS to call presentationAnchor(for:)?
- Does the window need to be key, main, visible, or foreground?
- Does ASWebAuthenticationSession.start() need to be called strictly on the main thread?
- Are additional entitlements, sandbox permissions, or Info.plist keys required for using ASWebAuthenticationSession in a sandboxed macOS application?
- Could the existence of a Login Item (SMAppService) affect the app’s ability to present the authentication sheet?
- Are there known restrictions for using custom URL schemes (myapp-auth://callback) on macOS?
- Is there any way to obtain more detailed diagnostics when start() silently fails to display UI?
Summary
In a sandboxed macOS application, ASWebAuthenticationSession starts without errors but never attempts to present its UI. Since presentationAnchor(for:) is never called, it seems macOS is blocking the presentation for some reason — possibly sandbox configuration, entitlements, or window state constraints.
Any guidance or suggestions would be greatly appreciated.
Thank you!