readme.md 4.95 KB
Newer Older
1
# Delay (for Swift 2.3)
Aral Balkan's avatar
Aral Balkan committed
2

3
Delay is an easy-to-use micro-library for delaying code execution in a cancellable manner. It uses Grand Central Dispatch and blocks.
Aral Balkan's avatar
Aral Balkan committed
4

5 6 7 8
This is the Swift 2.3 branch.

See `master` branch for the current release (Swift 2.2.1) version and the `swift-3` branch for the Swift 3.x version.

9 10 11 12
## Installation

[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)

13
Run the `./install` script to install the dependencies for the demo apps.
14

15
See the [detailed installation instructions](#detailed-installation-instructions), below, for instructions on how to add Delay to your own apps.
16

17
## Getting started
18

19
Run the `./dev` script and play with the iOS and OS X demo apps.
Aral Balkan's avatar
Aral Balkan committed
20

21
## Usage
Aral Balkan's avatar
Aral Balkan committed
22 23 24 25 26 27 28 29 30

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

31 32 33 34 35 36
```swift
delay(0.0)
{
  // Do something.
}
```
Aral Balkan's avatar
Aral Balkan committed
37 38 39

### Execute after an arbitrary number of seconds

40 41 42 43 44 45
```swift
delay(42.0)
{
  // Do something.
}
```
Aral Balkan's avatar
Aral Balkan committed
46 47
### Cancel before execution

48 49 50 51 52 53 54
```swift
let cancellableBlock = delay(42.0)
{
  // Do something.
}
cancellableBlock.cancel()
```
Aral Balkan's avatar
Aral Balkan committed
55 56 57

### Idiom: throttle user input

58 59
```swift
var cancellableCommand:CancellableDelayedCommand?
Aral Balkan's avatar
Aral Balkan committed
60

61
// …
Aral Balkan's avatar
Aral Balkan committed
62

63 64 65 66 67 68 69 70
// 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:
  // …
}
```
Aral Balkan's avatar
Aral Balkan committed
71 72 73

For example, you can use this to implement auto-complete without flooding the lookup method on every keystroke.

74 75 76
```swift
var textDidChangeHandler:NotificationHandler?
var cancellableAutoCompleteCommand:CancellableDelayedCommand?
Aral Balkan's avatar
Aral Balkan committed
77

78
// …
Aral Balkan's avatar
Aral Balkan committed
79

80 81 82 83 84
override func viewWillAppear()
{
	textDidChangeHandler = handle(NSControlTextDidChangeNotification, from: myTextInput)
  {
    /* with */ notification in
85

86
    let text = self.myTextInput.stringValue
87

88 89 90 91 92 93 94 95
    // 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
      // …
    }
  }
}
Aral Balkan's avatar
Aral Balkan committed
96

97 98 99 100 101 102
override func viewWillDisappear()
{
  cancellableAutoCompleteCommand.cancel()
  textDidChangeHandler.remove()
}
```
Aral Balkan's avatar
Aral Balkan committed
103 104 105 106 107 108 109

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.

110 111
## Detailed installation instructions

112
### Carthage
113

114
1. Add the framework to your `Cartfile`. e.g.,
115 116 117 118 119 120 121 122 123 124 125 126

	```git "git@source.ind.ie:project/delay.git" ~> 1.0```

2. [Follow the instructions on Carthage’s readme](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application).

### Manual

#### iOS

This requires hacking the Xcode project file but it’s still the most elegant way of doing things. If you want a better way, [dupe this radar for seamless support of fat frameworks in Xcode](http://openradar.appspot.com/radar?id=4951631992979456).

1. Build the framework target.
Aral Balkan's avatar
Aral Balkan committed
127
2. In Xcode, add the framework to the Embedded Binaries section.
128 129 130 131 132 133 134 135
3. Edit the `project.pbxproj` (in the <your-project>.xcodeproj folder) file and replace the line that reads something like:

	```A7E653511C2496F700988537 /* Delay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Delay.framework; path = "../../path/in/DerivedData/to/Delay.framework"; sourceTree = "<group>"; };```

	With:

	```A7E653511C2496F700988537 /* Delay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Delay.framework; path = "$(CONFIGURATION_BUILD_DIR)/Delay.framework"; sourceTree = "<group>"; };```

Aral Balkan's avatar
Aral Balkan committed
136
(In other words, you’re replacing the hardcoded path to the framework within your particular Derived Data folder with a generic one. This means that anyone else who checks out your project will get the correct framework.)
137 138 139 140 141 142 143

#### OS X

1. Just drag the framework into the Linked Frameworks and Binaries section of your project (under General).

(For an example of manually adding the framework, see the iOS and OS X demo apps that ship with this framework.)

Aral Balkan's avatar
Aral Balkan committed
144 145 146 147
## 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).)

148
Copyright © Aral Balkan.
149
Released with ♥ by [Ind.ie](https://ind.ie) under the MIT License.