Search code examples
iosswiftalamofiregrand-central-dispatch

How to wait for a multiply nested requests before creating another requests?


I have a Refresh Control. And when I pull it down I make 2 nested requests like that:

  httpClient.fetchCurrentWeather(...
    httpclient.fetchAnotherPartOfWeather(...
      delegate.showWeather(...)
    )
   )

I want to wait for first group to complete before calling another, because when i do like this i get my views blink because of many callback value updates.

upd: i do calls in interactor:

func retreiveCurrentDailyWeatherForecast() {
        guard let lat = locations?.first?.coordinate.latitude,
            let lon = locations?.first?.coordinate.longitude
            else { return }

        httpClient.fetchCurrentWeather(
            parameters: ["lat": lat,
                         "lon": lon, "units": "metric"],
            completionHandler: { dailyWeatherResult in
                switch dailyWeatherResult {
                case .success(let dailyWeatherResponse):
                    self.httpClient.fetchCurrentHourlyWeather(
                        parameters: ["lat": lat,
                                     "lon": lon, "units": "metric"],
                        completionHandler: { dailyWeeklyHourlyResult in
                            switch dailyWeeklyHourlyResult {
                            case .success(let dailyWeeklyHourlyResponse):
                                let weatherForecast =
                                    self.modelConverter.convertWeatherForecast(dailyWeatherResponse,
                                                                               dailyWeeklyHourlyResponse)
                                self.didRetreieveWeatherForecastFromNetwork(weatherForecast)
                            case .failure(let err):
                                print(err)
                            }
                    })
                case .failure(let err):
                    print(err)
                }
        })
    }

    func didRetreieveWeatherForecastFromNetwork(_ weatherForecast: WeatherForecast?) {
        if let weatherForecast = weatherForecast {
            self.presenter.didRetreiveWeatherForecast(weatherForecast)
        }
    }

Solution

  • Here you won't be needing anything too advanced. You just need to main a Boolean (example: isRequestIncomplete) to check if the response for the previous request was received. Here's an example of how you can achieve this:

    if isRequestIncomplete { return }
    isRequestIncomplete = true
    httpClient.fetchCurrentWeather(...
        httpclient.fetchAnotherPartOfWeather(...
          isRequestIncomplete = false
          delegate.showWeather(...)
        )
       )