# Delay Delay is an easy-to-use micro-library for delaying code execution in a cancellable manner. It uses Grand Central Dispatch and blocks. ## Installation [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) ### 1. Update your Cartfile **Swift 3 (latest version) – master** ``` git "git@source.ind.ie:project/delay.git" ``` For Swift 2.3, use the swift-2.3 branch: ``` git "git@source.ind.ie:project/delay.git" "swift-2.3" ``` ### 2. Add the framework to your Xcode project [Follow the instructions on Carthage’s readme](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). ## Demos 1. Run the `./install` script to install the dependencies for the demo apps. 2. Run the `./dev` script and play with the iOS and macOS demo apps. ## Usage Delay has three main use cases: * Delay execution of a block to the next stack frame (next frame of the runloop) * Delay execution by N seconds * Delay execution in a cancellable manner ### Execute on next stack frame ```swift _ = delay(0.0) { // Do something. } ``` ### Execute after an arbitrary number of seconds ```swift _ = delay(42.0) { // Do something. } ``` ### Cancel before execution ```swift let cancellableBlock = delay(42.0) { // Do something. } cancellableBlock.cancel() ``` ### Idiom: throttle user input ```swift var cancellableCommand:CancellableDelayedCommand? // … // Throttle expensive operation so it is performed at // most every second, no matter how often a signal is received. cancellableCommand = cancellableCommand?.reset() ?? delay(1.0) { // Perform expensive operation: // … } ``` For example, you can use this to implement auto-complete without flooding the lookup method on every keystroke. ```swift var textDidChangeHandler:NotificationHandler? var cancellableAutoCompleteCommand:CancellableDelayedCommand? // … override func viewWillAppear() { textDidChangeHandler = handle(NSControlTextDidChangeNotification, from: myTextInput) { /* with */ notification in let text = self.myTextInput.stringValue // Throttle auto-complete lookups to every 1/3rd of a second. cancellableAutoCompleteCommand = cancellableAutoCompleteCommand?.reset() ?? delay(0.3) { // Perform expensive operation: look-up text for auto-complete // … } } } override func viewWillDisappear() { cancellableAutoCompleteCommand.cancel() textDidChangeHandler.remove() } ``` Read more about the library [in this blog post](https://ind.ie/labs/blog/delay) on [Ind.ie Labs](https://ind.ie/labs). ## On performance Note that Delay is optimised for ease of authoring, beauty of interface, and clarity of intent. I haven’t run into performance issues and hence haven’t felt the need to run any benchmarks at the moment but [Evgenii Rtishchev’s purely-block-based CancelBlocks](https://github.com/katleta3000/CancelBlocks/blob/master/CancelBlocks.swift), on which my solution is based, is a lighter alternative should you need it. ## Credits Delay based on the work of [Evgenii Rtishchev](https://github.com/katleta3000/CancelBlocks) and [Chris Brind](http://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift/24318861#24318861) (with thanks to [Cezary Wojcik](http://stackoverflow.com/a/24034838/253485).) Copyright © Aral Balkan. Released with ♥ by [Ind.ie](https://ind.ie) under the MIT License.