{"id":23496342,"url":"https://github.com/aleksproger/debounced-closure","last_synced_at":"2026-05-17T06:34:22.552Z","repository":{"id":203958593,"uuid":"710786898","full_name":"aleksproger/debounced-closure","owner":"aleksproger","description":"Simple and flexible way to debounce closure calls in Swift","archived":false,"fork":false,"pushed_at":"2023-10-28T14:07:43.000Z","size":11,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-03-17T09:50:23.786Z","etag":null,"topics":["debounce","ios","macos","swift","textfield"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aleksproger.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-10-27T12:45:01.000Z","updated_at":"2024-11-19T22:27:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"85614a27-a477-4e93-ad9d-9bf281765808","html_url":"https://github.com/aleksproger/debounced-closure","commit_stats":{"total_commits":3,"total_committers":2,"mean_commits":1.5,"dds":"0.33333333333333337","last_synced_commit":"40764766645311b3b69d59448fe3af951ab53671"},"previous_names":["aleksproger/debounced-closure"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksproger%2Fdebounced-closure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksproger%2Fdebounced-closure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksproger%2Fdebounced-closure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksproger%2Fdebounced-closure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aleksproger","download_url":"https://codeload.github.com/aleksproger/debounced-closure/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250007309,"owners_count":21359770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debounce","ios","macos","swift","textfield"],"created_at":"2024-12-25T04:12:30.119Z","updated_at":"2025-10-20T09:13:23.078Z","avatar_url":"https://github.com/aleksproger.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DebouncedClosure\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Faleksproger%2Fdebounced-closure%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/aleksproger/debounced-closure)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Faleksproger%2Fdebounced-closure%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/aleksproger/debounced-closure)\n\n## Simple and flexible way to debounce closure calls\n\nDebouncedClosure is small and flexible implementation of debounce in modern Swift. \nIt allows to achieve debounce for any arbitrary closure calls using minimalistic and consice syntax.\n\n## Highlights\n\n* **Simple and flexible API** just wrap your closure into `debounced(_ block:, _ interval:)` and you will receive debounced implementation\n* **Tests** implementation contains tests\n* **Lightwheight** the package is small and won't introduce any overheds to SPM resolve process\n* **Flexible** underlying implementation can be changed from the client if neither `Task` nor `Timer` basic configurations are applicable\n\n\n## Usage\n\n#### Inject a debounced logger for observing TextField changes\n\nThe following code creates a debounced logger closure, which will fire events only after 1 second of idle in TextField\n\n```swift\nstruct ExampleViewOne: View {\n    @State \n    private var text = \"\"\n    let log: (String) -\u003e Void\n\n    var body: some View {\n        TextField(\"Text\", text: $text)\n            .onChange(of: text, perform: log)\n    }\n}\n\nstruct Logger {\n    static func log(_ message: String) { print(message) }\n}\n\nExampleViewOne(log: debounced(Logger.log, 1)) ✅\n\n```\n\n#### Inject a call to debounced function into, the client\n\nThe following code injects a call to `debounced(_ block:, _ interval:)` straight to the client code which called multiple times. \nIt is incorrect as `debounced(_ block:, _ interval:)` acts as a factory for the debounced closure and thus will simply create multiple debounced closures\n\n```swift\nstruct ExampleViewThree: View {\n    @State \n    private var text = \"\"\n\n    var body: some View {\n        TextField(\"Text\", text: $text)\n            .onChange(of: text, perform: debounced(Logger.log, .seconds(1))) ❌\n    }\n}\n\nstruct Logger {\n    static func log(_ message: String) { print(message) }\n}\n\nExampleViewThree()\n\n```\n\n#### Illustration of examples from Sources/Examples\n\nhttps://github.com/aleksproger/debounced-closure/assets/45671572/d7404e0a-9b35-40af-ac6b-7f534bf885f6\n\n#### Different function signatures\n\n- Using interval as `TimeInterval`\n```swift\ndebounced(Logger.log, 1)\n```\n- Using interval as `Duration`\n```swift\ndebounced(Logger.log, .seconds(1))\n```\n\n- Specifying one of predifined schedulers\n```swift\ndebounced(Logger.log, .timer(.seconds(1))) or debounced(Logger.log, .task(.seconds(1)))\n```\n\n- Specifying custom scheduler\n```swift\ndebounced(Logger.log) { block in CustomScheduler.start(with: block) }\n```\n\n## Requirements\n\n* iOS 14.0+\n* macOS 11.0+\n* watchOS 7.0+\n* tvOS 14.0+\n\n## Installation\n\n**SwiftPM:**\n\n```swift\n.package(url: \"https://github.com/aleksproger/debounced-closure.git\", .upToNextMajor(from: \"1.2.0\"))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleksproger%2Fdebounced-closure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faleksproger%2Fdebounced-closure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleksproger%2Fdebounced-closure/lists"}