Skip to content

Commit 8e649cb

Browse files
authored
Merge pull request #148 from ReactiveCocoa/andersio-readme-patch
A more detailed intro in the README.
2 parents e9b98e6 + 2c0958a commit 8e649cb

File tree

1 file changed

+98
-10
lines changed

1 file changed

+98
-10
lines changed

README.md

Lines changed: 98 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,108 @@
99
⚠️ [Still using Swift 2.x?][]
1010

1111
## What is ReactiveSwift?
12-
__ReactiveSwift__ offers composable, declarative and flexible primitives that are built around the grand concept of ___streams of values over time___. These primitives can be used to uniformly represent common Cocoa and generic programming patterns that are fundamentally an act of observation, e.g.:
12+
__ReactiveSwift__ offers composable, declarative and flexible primitives that are built around the grand concept of ___streams of values over time___.
1313

14-
* Delegate methods
15-
* Callback blocks
16-
* Notifications
17-
* Control actions and responder chain events
18-
* [Futures and promises](https://en.wikipedia.org/wiki/Futures_and_promises)
19-
* [Key-value observing](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html) (KVO)
14+
These primitives can be used to uniformly represent common Cocoa and generic programming patterns that are fundamentally an act of observation, e.g. delegate pattern, callback closures, notifications, control actions, responder chain events, [futures/promises](https://en.wikipedia.org/wiki/Futures_and_promises) and [key-value observing](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html) (KVO).
2015

2116
Because all of these different mechanisms can be represented in the _same_ way,
22-
it’s easy to declaratively chain and combine them together, with less spaghetti
17+
it’s easy to declaratively compose them together, with less spaghetti
2318
code and state to bridge the gap.
2419

25-
For more information about the concepts in ReactiveSwift, see the [Framework
26-
Overview][].
20+
### Core Reactive Primitives
21+
#### `Signal`: a unidirectional stream of events.
22+
The owner of a `Signal` has unilateral control of the event stream. Observers may register their interests in the future events at any time, but the observation would have no side effect on the stream or its owner.
23+
24+
It is like a live TV feed — you can observe and react to the content, but you cannot have a side effect on the live feed or the TV station.
25+
26+
```swift
27+
let channel: Signal<Program, NoError> = tvStation.channelOne
28+
channel.observeValues { program in ... }
29+
```
30+
31+
#### `Event`: the basic transfer unit of an event stream.
32+
A `Signal` may have any arbitrary number of events carrying a value, following by an eventual terminal event of a specific reason.
33+
34+
It is like a frame in a one-time live feed — seas of data frames carry the visual and audio data, but the feed would eventually be terminated with a special frame to indicate "end of stream".
35+
36+
#### `SignalProducer`: deferred work that creates a stream of values.
37+
`SignalProducer` defers work — of which the output is represented as a stream of values — until it is started. For every invocation to start the `SignalProducer`, a new `Signal` is created and the deferred work is subsequently invoked.
38+
39+
It is like a on-demand streaming service — even though the episode is streamed like a live TV feed, you can choose what you watch, when to start watching and when to interrupt it.
40+
41+
42+
```swift
43+
let frames: SignalProducer<VideoFrame, ConnectionError> = vidStreamer.streamAsset(id: tvShowId)
44+
let interrupter = frames.start { frame in ... }
45+
interrupter.dispose()
46+
```
47+
48+
#### `Property`: an observable box that always holds a value.
49+
`Property` is a variable that can be observed for its changes. In other words, it is a stream of values with a stronger guarantee than `Signal` — the latest value is always available, and the stream would never fail.
50+
51+
It is like the continuously updated current time offset of a video playback — the playback is always at a certain time offset at any time, and it would be updated by the playback logic as the playback continues.
52+
53+
```swift
54+
let currentTime: Property<TimeInterval> = video.currentTime
55+
print("Current time offset: \(currentTime.value)")
56+
currentTime.observeValues { timeBar.timeLabel.text = "\($0)" }
57+
```
58+
59+
#### `Action`: a serialized worker with a preset action.
60+
When being invoked with an input, `Action` apply the input and the latest state to the preset action, and pushes the output to any interested parties.
61+
62+
It is like an automatic vending machine — after choosing an option with coins inserted, the machine would process the order and eventually output your wanted snacks. Notice that the entire process is mutually exclusive — you cannot have the machine to serve two customers concurrently.
63+
64+
```swift
65+
// Purchase from the vending machine with a specific option.
66+
vendingMachine.purchase
67+
.apply(snackId)
68+
.startWithResults { result
69+
switch results {
70+
case let .success(snacks):
71+
print("Snack: \(snacks)")
72+
73+
case let .failure(error):
74+
// Out of stock? Insufficient fund?
75+
print("Transaction aborted: \(error)")
76+
}
77+
}
78+
79+
// The vending machine.
80+
class VendingMachine {
81+
let purchase: Action<(), [Snack], VendingMachineError>
82+
let coins: MutableProperty<Int>
83+
84+
// The vending machine is connected with a sales recorder.
85+
init(_ salesRecorder: SalesRecorder) {
86+
coins = MutableProperty(0)
87+
purchase = Action(state: coins, enabledIf: { $0 > 0 }) { coins, snackId in
88+
return SignalProducer { observer, _ in
89+
// The sales magic happens here.
90+
}
91+
}
92+
93+
// The sales recorders are notified for any successful sales.
94+
purchase.values.observeValues(salesRecorder.record)
95+
}
96+
}
97+
```
98+
99+
#### References
100+
101+
For more details about the concepts and primitives in ReactiveSwift, check these documentations out:
102+
103+
1. **[Framework Overview][]**
104+
105+
An overview of the behaviors and the suggested use cases of the ReactiveSwift primitives and utilities.
106+
107+
1. **[Basic Operators][]**
108+
109+
An overview of the operators provided to compose and transform these primitives.
110+
111+
1. **[Design Guidelines][]**
112+
113+
Contracts of the ReactiveSwift primitives, Best Practices with ReactiveSwift, and Guidelines on implementing custom operators.
27114

28115
## Example: online search
29116

@@ -335,6 +422,7 @@ If you need any help, please visit our [GitHub issues][] or [Stack Overflow][].
335422
[ReactiveCocoa]: https://github.com/ReactiveCocoa/ReactiveCocoa/#readme
336423
[Actions]: Documentation/FrameworkOverview.md#actions
337424
[Basic Operators]: Documentation/BasicOperators.md
425+
[Design Guidelines]: Documentation/DesignGuidelines.md
338426
[Carthage]: https://github.com/Carthage/Carthage/#readme
339427
[CocoaPods]: https://cocoapods.org/
340428
[CHANGELOG]: CHANGELOG.md

0 commit comments

Comments
 (0)