I'm using Amadeus API for flight search. Amadeus API requires that requests must not be more frequent than 1/100ms. I use the following code to limit the request frequency
for depDate in depDates{
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
AmadeusHelper.sharedInstance().searchAFlight(depAirport: depAirport, arrAirport: arrAirport, depDate: depDate, airlineCode: airlineCode, flightNumber: flightNum) { result in
switch result{
case .failure(let err):
print(err)
case .success(let flightOffer):
if let json = flightOffer.get(){
flightCandidate.offers?.append(json)
}
}
}
}
}
The above for-loop runs 4 loops. The searchAFlight function is essentially a wrapper of HTTP request. asyncAfter function will delay each request by 1 second. I thought this would be enough. However, I still get tooManyRequests error. When I was debugging, I followed the code step by step, which should took much longer to send out the requests. The requests should spread out across several minutes, long enough to satisfy the 100ms interval. Did I do something wrong here? Thanks.
===========Update=========
Based on Eric's comments, I changed the code to the following
var timeNow = DispatchTime.now() // each request is delayed with an increasing interval
for (index, depDate) in depDates.enumerated(){
DispatchQueue.main.asyncAfter(deadline: timeNow + Double(1*index)) {
AmadeusHelper.sharedInstance().searchAFlight(depAirport: depAirport, arrAirport: arrAirport, depDate: depDate, airlineCode: airlineCode, flightNumber: flightNum) { result in
switch result{
case .failure(let err):
print(err)
case .success(let flightOffer):
if let json = flightOffer.get(){
flightCandidate.offers?.append(json)
}
}
}
}
}
Unfortunately, I still get tooManyRequest error.
DispatchQueue.main.asyncAfter(deadline: .now() + 1)is doing is that it offsets the moment the requests will start, but they still are executed very fast in sequence (because of the loop) once the first one has started (they're all offset with the same time). - Eric Ayasemaphore, but just send only one request), it works fine. I will trysemaphoreandtimer. But one thing here is that, the API sometimes doesn't call the completion handler. The example you gave has asemaphore.signal()in the completion handler. Any suggestion to add some timeout logic here? Thanks! - Feng