Rate Limiting on iOS
Whenever you enter an address into Google Maps or search for a video on YouTube, you may have noticed that the auto-complete suggestions update at regular intervals rather than with every change to the search query.
When you consider the scale of these platforms, limiting requests in this manner is a necessary optimization. This helps prevent unnecessary HTTP requests while still ensuring a smooth user experience.
Today, we'll look at a simple implementation you can use to replicate this behavior in your applications.
Let's continue with our auto-complete suggestions use case and imagine we have a function that makes an asynchronous HTTP request and returns an updated list of suggestions:
func getAutocompleteSuggestions(from query: String,
completion: (([String]) -> Void)?)
Ideally, we would like to be able to call this function directly within the delegate callback of our searchBar
or textField
and have some other mechanism that guarantees the request fires only once every X
seconds.
Implementation
We can create the following ThrottleExecution
utility to handle these requirements:
struct ThrottleExecution {
private static var previousExecution = Date.distantPast
static func execute(minimumInterval: TimeInterval, queue: DispatchQueue, _ block: @escaping () -> Void) {
if abs(previousExecution.timeIntervalSinceNow) > minimumInterval {
previousExecution = Date()
queue.async { block() }
}
}
}
This method ensures that the block
is only executed once in the TimeInterval
specified. So, if this method is called 100 times within 9 seconds and we were to pass 5 seconds as the minimumInterval
, the block will only be executed twice; the first time the method is called and once more 5 seconds later.
Usage
With just this simple ThrottleExecution
utility we can effectively limit the execution frequency and customize the DispatchQueue
of any task in our application:
ThrottleExecution.execute(minimumInterval: 0.3, queue: .main) { [weak self] in
guard let self = self, let query = self.searchTextField.text else { return }
self.getAutocompleteSuggestions(from: query) { searchSuggestions in
// Update UI with new searchSuggestions
}
}
If you're interested in more articles about iOS Development & Swift, check out my YouTube channel or follow me on Twitter.
If you're an indie iOS developer, make sure to check out my newsletter:
I feature a new developer every issue, so feel free to submit your indie iOS apps!
Do you have an iOS Interview coming up?
Check out my book Ace The iOS Interview!