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
1. Update your Cartfile
Swift 3 (latest version)
git "git@source.ind.ie:project/delay.git" ~> 3.0
For Swift 2.3, use the swift-2.3 branch:
git "git@source.ind.ie:project/delay.git" "swift-2.3"
To stay on Swift 2.2, use the 2.0.3 tag:
git "git@source.ind.ie:project/handle.git" ~> 2.0.3
2. Add the framework to your Xcode project
Follow the instructions on Carthage’s readme.
Demos
- Run the
./installscript to install the dependencies for the demo apps. - Run the
./devscript 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
_ = delay(0.0)
{
// Do something.
}
Execute after an arbitrary number of seconds
_ = delay(42.0)
{
// Do something.
}
Cancel before execution
let cancellableBlock = delay(42.0)
{
// Do something.
}
cancellableBlock.cancel()
Idiom: throttle user input
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.
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 on 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, on which my solution is based, is a lighter alternative should you need it.
Credits
Delay based on the work of Evgenii Rtishchev and Chris Brind (with thanks to Cezary Wojcik.)
Copyright © Aral Balkan. Released with ♥ by Ind.ie under the MIT License.