Skip to content

Commit c42b30e

Browse files
committed
Merge branch 'master' into producer-lift
2 parents 1a48d8f + 3495369 commit c42b30e

File tree

14 files changed

+533
-195
lines changed

14 files changed

+533
-195
lines changed

.travis.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
language: objective-c
2-
osx_image: xcode8.1
2+
osx_image: xcode8.2
33
before_install: true
44
install: true
55
git:
@@ -24,11 +24,12 @@ matrix:
2424
env:
2525
- XCODE_SDK=iphonesimulator
2626
- XCODE_ACTION="build-for-testing test-without-building"
27-
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 6s"
27+
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 6s,OS=10.1"
28+
- xcode_scheme: ReactiveSwift-iOS
2829
env:
2930
- XCODE_SDK=iphonesimulator
3031
- XCODE_ACTION="build-for-testing test-without-building"
31-
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 5"
32+
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 5,OS=10.1"
3233
- xcode_scheme: ReactiveSwift-tvOS
3334
env:
3435
- XCODE_SDK=appletvsimulator

README.md

Lines changed: 135 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,111 @@
88
🎉 [Getting Started](#getting-started)
99
⚠️ [Still using Swift 2.x?][]
1010

11+
12+
🚄 [Release Roadmap](#release-roadmap)
1113
## 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.:
14+
__ReactiveSwift__ offers composable, declarative and flexible primitives that are built around the grand concept of ___streams of values over time___.
1315

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)
16+
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).
2017

2118
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
19+
it’s easy to declaratively compose them together, with less spaghetti
2320
code and state to bridge the gap.
2421

25-
For more information about the concepts in ReactiveSwift, see the [Framework
26-
Overview][].
22+
### Core Reactive Primitives
23+
#### `Signal`: a unidirectional stream of events.
24+
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.
25+
26+
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.
27+
28+
```swift
29+
let channel: Signal<Program, NoError> = tvStation.channelOne
30+
channel.observeValues { program in ... }
31+
```
32+
33+
#### `Event`: the basic transfer unit of an event stream.
34+
A `Signal` may have any arbitrary number of events carrying a value, following by an eventual terminal event of a specific reason.
35+
36+
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".
37+
38+
#### `SignalProducer`: deferred work that creates a stream of values.
39+
`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.
40+
41+
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.
42+
43+
44+
```swift
45+
let frames: SignalProducer<VideoFrame, ConnectionError> = vidStreamer.streamAsset(id: tvShowId)
46+
let interrupter = frames.start { frame in ... }
47+
interrupter.dispose()
48+
```
49+
50+
#### `Property`: an observable box that always holds a value.
51+
`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.
52+
53+
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.
54+
55+
```swift
56+
let currentTime: Property<TimeInterval> = video.currentTime
57+
print("Current time offset: \(currentTime.value)")
58+
currentTime.observeValues { timeBar.timeLabel.text = "\($0)" }
59+
```
60+
61+
#### `Action`: a serialized worker with a preset action.
62+
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.
63+
64+
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.
65+
66+
```swift
67+
// Purchase from the vending machine with a specific option.
68+
vendingMachine.purchase
69+
.apply(snackId)
70+
.startWithResults { result
71+
switch results {
72+
case let .success(snacks):
73+
print("Snack: \(snacks)")
74+
75+
case let .failure(error):
76+
// Out of stock? Insufficient fund?
77+
print("Transaction aborted: \(error)")
78+
}
79+
}
80+
81+
// The vending machine.
82+
class VendingMachine {
83+
let purchase: Action<(), [Snack], VendingMachineError>
84+
let coins: MutableProperty<Int>
85+
86+
// The vending machine is connected with a sales recorder.
87+
init(_ salesRecorder: SalesRecorder) {
88+
coins = MutableProperty(0)
89+
purchase = Action(state: coins, enabledIf: { $0 > 0 }) { coins, snackId in
90+
return SignalProducer { observer, _ in
91+
// The sales magic happens here.
92+
}
93+
}
94+
95+
// The sales recorders are notified for any successful sales.
96+
purchase.values.observeValues(salesRecorder.record)
97+
}
98+
}
99+
```
100+
101+
#### References
102+
103+
For more details about the concepts and primitives in ReactiveSwift, check these documentations out:
104+
105+
1. **[Framework Overview][]**
106+
107+
An overview of the behaviors and the suggested use cases of the ReactiveSwift primitives and utilities.
108+
109+
1. **[Basic Operators][]**
110+
111+
An overview of the operators provided to compose and transform these primitives.
112+
113+
1. **[Design Guidelines][]**
114+
115+
Contracts of the ReactiveSwift primitives, Best Practices with ReactiveSwift, and Guidelines on implementing custom operators.
27116

28117
## Example: online search
29118

@@ -278,7 +367,7 @@ If you use [Carthage][] to manage your dependencies, simply add
278367
ReactiveSwift to your `Cartfile`:
279368

280369
```
281-
github "ReactiveCocoa/ReactiveSwift" "1.0.0-alpha.4"
370+
github "ReactiveCocoa/ReactiveSwift" "1.0.0-rc.1"
282371
```
283372

284373
If you use Carthage to build your dependencies, make sure you have added `ReactiveSwift.framework`, and `Result.framework` to the "_Linked Frameworks and Libraries_" section of your target, and have included them in your Carthage framework copying build phase.
@@ -289,7 +378,7 @@ If you use [CocoaPods][] to manage your dependencies, simply add
289378
ReactiveSwift to your `Podfile`:
290379

291380
```
292-
pod 'ReactiveSwift', '1.0.0-alpha.4'
381+
pod 'ReactiveSwift', '1.0.0-rc.1'
293382
```
294383

295384
#### Swift Package Manager
@@ -298,7 +387,7 @@ If you use Swift Package Manager, simply add ReactiveSwift as a dependency
298387
of your package in `Package.swift`:
299388

300389
```
301-
.Package(url: "https://github.com/ReactiveCocoa/ReactiveSwift.git", "1.0.0-alpha.4")
390+
.Package(url: "https://github.com/ReactiveCocoa/ReactiveSwift.git", "1.0.0-rc.1")
302391
```
303392

304393
#### Git submodule
@@ -332,9 +421,42 @@ We also provide a great Playground, so you can get used to ReactiveCocoa's opera
332421
## Have a question?
333422
If you need any help, please visit our [GitHub issues][] or [Stack Overflow][]. Feel free to file an issue if you do not manage to find any solution from the archives.
334423

424+
## Release Roadmap
425+
**Current Stable Release:**<br />[![GitHub release](https://img.shields.io/github/release/ReactiveCocoa/ReactiveSwift.svg)](https://github.com/ReactiveCocoa/ReactiveSwift/releases)
426+
427+
### In Development: ReactiveSwift 1.0
428+
It targets Swift 3.0.x. The tentative schedule of a Gold Master release is January 2017.
429+
430+
A Release Candidate would be released after an important bug fix and an API renaming PR are cleared, which should happen no later than Christmas 2016.
431+
432+
A point release is expected with performance optimizations.
433+
434+
### Plan of Record
435+
#### ReactiveSwift 2.0
436+
It targets Swift 3.1.x. The estimated schedule is Spring 2017.
437+
438+
The release contains breaking changes. But they are not expected to affect the general mass of users, but only a few specific use cases.
439+
440+
The primary goal of ReactiveSwift 2.0 is to remove single-implementation protocols, e.g. `SignalProtocol`, `SignalProducerProtocol`, that serve as a workaround to **concrete same-type requirements**.
441+
442+
ReactiveSwift 2.0 may include other proposed breaking changes.
443+
444+
As resilience would be enforced in Swift 4.0, it is important for us to have a clean and steady API to start with. The expectation is to **have the API cleanup and the reviewing to be concluded in ReactiveSwift 2.0**, before we move on to ReactiveSwift 3.0 and Swift 4.0. Any contribution to help realising this goal is welcomed.
445+
446+
#### ReactiveSwift 3.0
447+
It targets Swift 4.0.x. The estimated schedule is late 2017.
448+
449+
The release may contain breaking changes, depending on what features are being delivered by Swift 4.0.
450+
451+
ReactiveSwift 3.0 would focus on two main goals:
452+
453+
1. Swift 4.0 Resilience
454+
2. Adapt to new features introduced in Swift 4.0 Phase 2.
455+
335456
[ReactiveCocoa]: https://github.com/ReactiveCocoa/ReactiveCocoa/#readme
336457
[Actions]: Documentation/FrameworkOverview.md#actions
337458
[Basic Operators]: Documentation/BasicOperators.md
459+
[Design Guidelines]: Documentation/DesignGuidelines.md
338460
[Carthage]: https://github.com/Carthage/Carthage/#readme
339461
[CocoaPods]: https://cocoapods.org/
340462
[CHANGELOG]: CHANGELOG.md

0 commit comments

Comments
 (0)