swiftaws-amplify

Syncronization issue, idToken is not set before sending Api Call


I am new to Swift, I wish someone could assist me. The bearerToken function updates the idToken variable which is used for getMedicalData() function The problem is that getMedicalData() function is run before the idToken's value is updated by the bearerToken(). This causes getMedicalData() to use an empty idToken variable. How can I syncronize it so that getMedicalData() is ran after all of bearerToken() is ran.

Main Function where I am calling the getMedicalData() and bearerToken():

    func login(username: String, password: String) {
        _ = Amplify.Auth.signIn(
            username: username,
            password: password
        ) { [weak self] result in
            switch result {
            case .success(let signInResult):
                print(SignInResult.self)
                if signInResult.isSignedIn {
//calling the two functions
                    TokenManager.shared.bearerToken()
                    getMedicalData()

                    DispatchQueue.main.async {
                        self?.getCurrentAuthUser()
                    }
                }
                
            case .failure(let error):
                print("Login error:", error)
            }
        }
    }

bearerToken Function:

    func bearerToken() {
        _ = Amplify.Auth.fetchAuthSession { result in
            switch result {
            case .success(let session):
                if(session.isSignedIn) {
                    if let sess = session as? AWSAuthCognitoSession {
                        let result = sess.getCognitoTokens()
                        switch result {
                        case .success(let tokens):
                            self.idToken = String(tokens.idToken)
                            self.refreshToken = tokens.refreshToken
                        case .failure(let error):
                            print("Fetch user tokens failed with error \(error)")
                        }
                    }
                }
            case .failure(let error):
                print("Fetch session failed with error \(error)")
            }
        }
    }

Solution

  • You can use async-await or completion handler.

    Here you can use it as a completion handler

    func bearerToken(completion: @escaping () -> Void) {
    
            _ = Amplify.Auth.fetchAuthSession { result in
                switch result {
                case .success(let session):
                    if(session.isSignedIn) {
                        if let sess = session as? AWSAuthCognitoSession {
                            let result = sess.getCognitoTokens()
                            switch result {
                            case .success(let tokens):
                                self.idToken = String(tokens.idToken)
                                self.refreshToken = tokens.refreshToken
    
                                completion()
    
                            case .failure(let error):
                                print("Fetch user tokens failed with error \(error)")
                            }
                        }
                    }
                case .failure(let error):
                    print("Fetch session failed with error \(error)")
                }
            }
        }
    

    and in your Main function

    
           switch result {
                case .success(let signInResult):
                    print(SignInResult.self)
                    if signInResult.isSignedIn {
                        //calling the two functions
                        TokenManager.shared.bearerToken {
    
                            getMedicalData()
    
                            DispatchQueue.main.async {
                                self?.getCurrentAuthUser()
                            }
                        }
                    }
                    
           case .failure(let error):
                    print("Login error:", error)
           }