Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I debounce a method call?

I'm trying to use a UISearchView to query google places. In doing so, on text change calls for my UISearchBar, I'm making a request to google places. The problem is I'd rather debounce this call to only request once per 250 ms in order to avoid unnecessary network traffic. I'd rather not write this functionality myself, but I will if I need to.

I found: https://gist.github.com/ShamylZakariya/54ee03228d955f458389 , but I'm not quite sure how to use it:

func debounce( delay:NSTimeInterval, #queue:dispatch_queue_t, action: (()->()) ) -> ()->() {      var lastFireTime:dispatch_time_t = 0     let dispatchDelay = Int64(delay * Double(NSEC_PER_SEC))      return {         lastFireTime = dispatch_time(DISPATCH_TIME_NOW,0)         dispatch_after(             dispatch_time(                 DISPATCH_TIME_NOW,                 dispatchDelay             ),             queue) {                 let now = dispatch_time(DISPATCH_TIME_NOW,0)                 let when = dispatch_time(lastFireTime, dispatchDelay)                 if now >= when {                     action()                 }             }     } } 

Here is one thing I've tried using the above code:

let searchDebounceInterval: NSTimeInterval = NSTimeInterval(0.25)  func findPlaces() {     // ... }  func searchBar(searchBar: UISearchBar!, textDidChange searchText: String!) {     debounce(         searchDebounceInterval,         dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT),         self.findPlaces     ) } 

The resulting error is Cannot invoke function with an argument list of type '(NSTimeInterval, $T5, () -> ())

How do I use this method, or is there a better way to do this in iOS/Swift.

like image 543
Parris Avatar asked Nov 25 '14 00:11

Parris


People also ask

How do you use debounce function?

The debounce() function forces a function to wait a certain amount of time before running again. The function is built to limit the number of times a function is called. The Send Request() function is debounced. Requests are sent only after fixed time intervals regardless of how many times the user presses the button.

How do you use debounce in a functional component?

Debouncing enforces that there is a minimum time gap between two consecutive invocations of a function call. For example, a debounce interval of 500ms means that if 500ms hasn't passed from the previous invocation attempt, we cancel the previous invocation and schedule the next invocation of the function after 500ms.


2 Answers

Here's an option for those not wanting to create classes/extensions:

Somewhere in your code:

var debounce_timer:Timer? 

And in places you want to do the debounce:

debounce_timer?.invalidate() debounce_timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in      print ("Debounce this...")  } 
like image 102
Khrob Avatar answered Sep 19 '22 21:09

Khrob


If you like to keep things clean, here's a GCD based solution that can do what you need using familiar GCD based syntax: https://gist.github.com/staminajim/b5e89c6611eef81910502db2a01f1a83

DispatchQueue.main.asyncDeduped(target: self, after: 0.25) { [weak self] in      self?.findPlaces() } 

findPlaces() will only get called one time, 0.25 seconds after the last call to asyncDuped.

like image 37
staminajim Avatar answered Sep 18 '22 21:09

staminajim