Synchronize nested async network requests inside a while loop by using Semaphores

I have a func that gets a list of Players. When i fetch the players i need only to show those who belongs to the current Team so i am showing only a subset of the original list by filtering them. I don't know in advance, before making the request, how much players belong to the Team selected by the User, so i may need to do additional requests until i can display on the TableView at least 10 rows of Players. The User by pulling up from the bottom of the TableView can request more players to display. To do this i am calling a first async func request which in turn calls, inside a while, another nested async func request. Here a code to give you an idea of what i am trying to do:

 let semaphore = DispatchSemaphore(value: 0)

 func getTeamPlayersRequest() {

    nbaService.getTeamPlayers(...) 
    { 
      (result) in

      switch result
      {
        case .success(let playersModel):

              if let validCurrentPage = currentPageTmp ,
                 let validTotalPages = totalPagesTmp ,
                 let validNextPage = self.getTeamPlayersListNextPage()
              
              {
                  while self.playersToShowTemp.count < 10 && self.currentPage < validTotalPages 
                  {
                      self.currentPage = validNextPage //global var
                      self.fetchMorePlayers()
                      self.semaphore.wait() //global semaphore
                  }
              }
            

        case .failure(let error):

          //some code...

      }

    })

 }

private func fetchMorePlayers(){

// Completion handler of the following function is never called..

  nbaService.getTeamPlayers(requestedPage: currentPage, completion: { 

    (result) in

    switch result
      {
        case .success(let playersModel):

            if  let validPlayerList = playersList,
                let validPlayerListData = validPlayerList.data,
                let validTeamModel = self.teamPlayerModel,
                let validNextPage = self.getTeamPlayersListNextPage()
            {

                for player in validPlayerListData 
                {
                    if ( validTeamModel.id == player.team?.id)
                    {
                        self.playersToShowTemp.append(player)
                    }
                }

            }

            self.currentPage = validNextPage
            self.semaphore.signal() //global semaphore


        case .failure(let error):

          //some code...

      }


   }
     
}

I have tried both with DispatchGroup and Semaphore but i don't get it what i am doing wrong. I debugged the code and saw that the first async call get executed in a different queue (not the main queue) and a different thread. The nested async call getexecuted on a different thread but i don't know if it's the same concurrent queue of the first async call.

The completion handler of thenested call it's never called. Does anyone know why? is the self.semaphore.wait(), even if it get executed after the fetchMorePlayers() return, blocking/preventing the nested async completion handler to be called?

I am noticing through the Debugger that the completion() in the Xcode vars window has the note "swift partial apply forwarder for closure #1"

It's impossible for me to understand this code without more information. What you posted is in complete. What are the parameters and body of service.getTeamPlayers? Where do these variables come from: currentPageTmp, totalPagesTmp, playersList. You need to provide information about the global variables that you referenced as well.

How could anyone possibly tell you why the completion handler of a function is never called if you don't provide the body of the function?

What do you mean? i have provided the body of both functions, what do you need more?

The body of getTeamPlayers was not provided in the code you posted. In your original question, you asked why the completion handler passed to this function was not called.
And yes, I need a lot more information to help you.

Terms of Service

Privacy Policy

Cookie Policy