0

I want my application to return to the original API call. Here is a sample code:

func getDataFromServer()
{
   guard let apiUrl = URL(string: endPoint) else {
        return
    }
    getAccessTokenValue( completionHandler:{ accesstoken in
        //if access token is valid continue to get data
        //.......
         let task = self.apiSession.dataTask(with: apiRequest, completionHandler:  {
            (data, response, error) in
             //Manage response/data/error
           })
           task.resume()
        })

}


func getAccessTokenValue(completionHandlerResult : @escaping (_ accesstoken : String) -> ())
{
  var hasAccessTokenExpired = true
  // do some calculation

  //check if access token has expired
  if hasAccessTokenExpired
  {
     self.renewAccessToken(completionHandler: { accessTokenValue in

      completionHandlerResult(accessTokenValue)})
  }
  else{
       completionHandlerResult( accessToken) //return the current access token
  }

}


func  static func renewAccessToken (completionHandler : @escaping   (_ accessTokenValue:String) -> ()) //
{
    //another API call to refresh Access Token
    //.......
         let task = self.apiSession.dataTask(with: apiRequest, completionHandler:  {
            (data, response, error) in
             //Manage response/data/error
             //read access token from response
             completionHandler(accessToken)
           })
           task.resume()

}

The problem I am facing is when my access token is no longer valid, the API for refresh token is fired but by the time the data task in renewAccessToken is completed, my application has already executed the end of getAccessTokenValue and getDataFromServer. So the API which should have been executed after getting the refreshed access token (in getDataFromServer's completion handler for getAccessTokenValue), is no longer fired.

I am not able to figure out where I have gone wrong.

Kiah_Dev
  • 133
  • 1
  • 8
  • I do not understand the problem, from the code above when call"getDataFromServer" it first get the access token then it execute the api request. – Iosif Jun 04 '18 at 10:54
  • Put a break point and make sure you call the completion handler in `renewAccessToken` . – Todor Brachkov Jun 04 '18 at 11:00
  • @TodorBrachkov the completion handler for renewAccessToken is called but it does not return to getAccessTokenValue. The problem is when task.resume() is called in renewAccessToken, it goes to getAccessTokenValue's end, then to getDataFromServer's end, then back to where I had invoked getDataFromServer. The control comes back to the dataTask in renewAccessToken but after its completion it does not return to getAccessTokenValue. – Kiah_Dev Jun 04 '18 at 11:04
  • @TodorBrachkov - Resolved the issue. It was a problem with completion handler not being called when the API failed. I added that and now it works perfectly. Thank you :) – Kiah_Dev Jun 04 '18 at 12:48
  • Nice that you solved it, sorry for the late response. – Todor Brachkov Jun 04 '18 at 13:56
  • No issues at all. In fact, I put break points in all possible flows to trace where it was going and that's how I could find the problem. So thanks to you! :) @TodorBrachkov – Kiah_Dev Jun 04 '18 at 14:31

1 Answers1

0

Resolved the issue. It was a problem with completion handler not being called when the API failed. I added that and now it works perfectly.

Kiah_Dev
  • 133
  • 1
  • 8