How to wait oauth callback for triggering handleRedirectURL in swift

Viewed 19

I've those methods

func runOauth(){
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    appDelegate.oauth2!.afterAuthorizeOrFail = self.callBackOAuth

    var url:URL?
    do{
        url = try appDelegate.oauth2!.authorizeURL(withRedirect:"kronos://oauth/callback", scope: "auth",params: ["tg":"addon/kronos/main","idx":"login.OAuth","formId":"iOS"])
        do{
            let authorizer = appDelegate.oauth2!.authorizer as! OAuth2Authorizer
            safariVC = try authorizer.authorizeSafariEmbedded(from: self,at: url!)
            
        }
      /*catch error*/
    }
}


func callBackOAuth(authParameters:OAuth2JSON!, error: OAuth2Error!){
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        if (error ==  nil && appDelegate.oauth2!.accessToken != nil){//OAuth succeed in
            self.keychain!.set(appDelegate.oauth2!.accessToken!,forKey:"Token")
            appDelegate.reloadView()
        }else {/*handle errors*/}
    }

and in AppDelegate

func application(_ app: UIApplication,
                  open url: URL,
                  options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
        let site=components?.host
        if site == "oauth"{//OAuth terminated
            if components?.path == "/callback" {
                let viewController = self.window?.rootViewController as! ViewController
                self.oauth2!.handleRedirectURL(url)
                viewController.hideSafariView()
            }
        }
        return true
    }

My issue is that as I trigger runOauth like that it happens that application is called before callBackOAuth so after oauth viewDidAppear is recalled but with keychain token not set, so here is a way to "wait" in application that token is not nil

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        //initialize OAuth2 config parameters
        appDelegate.oauth2 = OAuth2CodeGrant(settings: OAuthParams  )
        appDelegate.oauth2!.authConfig.authorizeContext = KronosWebsite?.window
        appDelegate.oauth2!.useKeychain = false
        appDelegate.oauth2!.authConfig.authorizeEmbeddedAutoDismiss = true
        appDelegate.oauth2!.logger = OAuth2DebugLogger(.debug)
        appDelegate.oauth2!.afterAuthorizeOrFail = self.callBackOAuth

        let token=self.keychain!.get("Token")        
        if(token == nil){//no token found, we launch the OAuth
            runOauth()
        } 
}

EDIT: I've tried to use a DispatchGroup with no success:

groupOauth.enter() in runOauth

groupOauth.leave() in callBackOAuth

and in AppDelegate::application

 viewController.groupOauth.notify(queue: DispatchQueue.main) {
    self.oauth2!.handleRedirectURL(url)
    viewController.hideSafariView()
}
1 Answers

I've a solution by deporting the call of the URL which logs the user (with the Oauth token stored in keychain) from viewDidAppear to viewDidLoad

Related