How can I debounce a method call in Swift 4?

Debouncing calls is great for situations where a repeating user action can cause network requests to happen. The problem is that the user’s actions can generate many requests in a short period of time, which can be slow to respond on a cellular network.

This also applies to other types of wireless communication, such as BLE.

Here is an implementation of a Debouncer class in Swift 4. Github Gist link

import Foundation

class Debouncer {

    /**
     Create a new Debouncer instance with the provided time interval.

     - parameter timeInterval: The time interval of the debounce window.
    */
    init(timeInterval: TimeInterval) {
        self.timeInterval = timeInterval
    }

    typealias Handler = () -> Void

    /// Closure to be debounced.
    /// Perform the work you would like to be debounced in this handler.
    var handler: Handler?

    /// Time interval of the debounce window.
    private let timeInterval: TimeInterval

    private var timer: Timer?

    /// Indicate that the handler should be invoked.
    /// Begins the debounce window with the duration of the time interval parameter.
    func renewInterval() {
        // Invalidate existing timer if there is one
        timer?.invalidate()
        // Begin a new timer from now
        timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: false, block: { [weak self] timer in
            self?.handleTimer(timer)
        })
    }

    private func handleTimer(_ timer: Timer) {
        guard timer.isValid else {
            return
        }
        handler?()
        handler = nil
    }

}

The Debounce class is straight forward to use:

// Create a Debouncer with a half-second time interval
let debouncer = Debouncer(timeInterval: 0.5)

debouncer.handler = {
    // Send the debounced network request here
    print("Send network request")
}

func textDidChangeDelegateMethod() {
    // When the user performs a repeating action, such as entering text, invoke the `renewInterval` method
    debouncer.renewInterval()
}

PS: Interestingly, the term debounce comes from electrical engineering. “Bouncing is the tendency of any two metal contacts in an electronic device to generate multiple signals as the contacts close or open.” (http://whatis.techtarget.com/definition/debouncing) So a de-bouncing circuit cleans up this bouncing between the signals, by providing a single signal.


Subscribe to the newsletter to stay up to date with new articles.


One thought on “How can I debounce a method call in Swift 4?”

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax