Search code examples
iosxcodekeycloakcapacitoraswebauthenticationsession

Capacitor plugin with ASWebAuthenticationSession: must be used from main thread only


I'm trying to get rid off an annoying warning/error in the xcode console. I've implemented a custom plugin to open Keycloak using ASWebAuthenticationSession and I'm having issue figuring out how to call the main thread window.

This is the code:

@available(iOS 13.0, *)
@objc(KeycloakPlugin)
public class KeycloakPlugin: CAPPlugin, ObservableObject, ASWebAuthenticationPresentationContextProviding {
    var webAuthSession: ASWebAuthenticationSession?
    
    public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return self.bridge?.webView?.window ?? ASPresentationAnchor()
    }
    

This line compains when I open the external url for the authentication:

return self.bridge?.webView?.window ?? ASPresentationAnchor()

in this case I get:

UIView.window must be used from main thread only

Do you have any idea how to fix this?


Solution

  • Maybe this helps:

    https://capacitorjs.com/docs/core-apis/ios

    If you wrap your code in DispatchQueue.main.async, it should remove the warning. It also works with DispatchQueue.main.sync, depending on the implementation.

    Something like this:

    @objc(MyPlugin)
    public class MyPlugin: CAPPlugin, ASWebAuthenticationPresentationContextProviding {
        
        @objc func myPluginMethod(_ call: CAPPluginCall) {
    //        do something here
        }
    
        public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
            var view: ASPresentationAnchor?
            DispatchQueue.main.sync {
                view = self.bridge?.webView?.window
                // or use async and do something here, e.g. create an implementation instance and pass the view
            }
            return view ?? ASPresentationAnchor()
        }
    }