Name Last Update
Delay Loading commit data...
Delay.xcworkspace Loading commit data...
DelayDemo-iOS Loading commit data...
DelayDemo-macOS Loading commit data...
.gitignore Loading commit data...
Cartfile.private Loading commit data...
Cartfile.resolved Loading commit data...
dev Loading commit data...
install Loading commit data...
readme.md Loading commit data...
update Loading commit data...

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

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

  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

_ = 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.