DebouncedClosure is small and flexible implementation of debounce in modern Swift. It allows to achieve debounce for any arbitrary closure calls using minimalistic and consice syntax.
- Simple and flexible API just wrap your closure into
debounced(_ block:, _ interval:)
and you will receive debounced implementation - Tests implementation contains tests
- Lightwheight the package is small and won't introduce any overheds to SPM resolve process
- Flexible underlying implementation can be changed from the client if neither
Task
norTimer
basic configurations are applicable
The following code creates a debounced logger closure, which will fire events only after 1 second of idle in TextField
struct ExampleViewOne: View {
@State
private var text = ""
let log: (String) -> Void
var body: some View {
TextField("Text", text: $text)
.onChange(of: text, perform: log)
}
}
struct Logger {
static func log(_ message: String) { print(message) }
}
ExampleViewOne(log: debounced(Logger.log, 1)) ✅
The following code injects a call to debounced(_ block:, _ interval:)
straight to the client code which called multiple times.
It is incorrect as debounced(_ block:, _ interval:)
acts as a factory for the debounced closure and thus will simply create multiple debounced closures
struct ExampleViewThree: View {
@State
private var text = ""
var body: some View {
TextField("Text", text: $text)
.onChange(of: text, perform: debounced(Logger.log, .seconds(1))) ❌
}
}
struct Logger {
static func log(_ message: String) { print(message) }
}
ExampleViewThree()
Debounce.mov
- Using interval as
TimeInterval
debounced(Logger.log, 1)
- Using interval as
Duration
debounced(Logger.log, .seconds(1))
- Specifying one of predifined schedulers
debounced(Logger.log, .timer(.seconds(1))) or debounced(Logger.log, .task(.seconds(1)))
- Specifying custom scheduler
debounced(Logger.log) { block in CustomScheduler.start(with: block) }
- iOS 14.0+
- macOS 11.0+
- watchOS 7.0+
- tvOS 14.0+
SwiftPM:
.package(url: "https://github.com/aleksproger/debounced-closure.git", .upToNextMajor(from: "1.2.0"))