Replaces `>-` with protocol extensions. Unit tests pass. Adds `CHANGELOG.md`

This commit is contained in:
Krunoslav Zaher 2015-08-10 01:43:30 +02:00
parent 0ca9c90f6a
commit 2c33f7a89a
108 changed files with 1877 additions and 2124 deletions

15
CHANGELOG.md Normal file
View File

@ -0,0 +1,15 @@
#Change Log
All notable changes to this project will be documented in this file.
---
## [2.0](https://github.com/ReactiveX/RxSwift/pull/50) (WIP)
####Updated
* Adds `ObservableType`
* Moved from using `>-` operator to protocol extensions
* Change from `disposeBag.addDisposable` to `disposable.addDisposableTo`
* Changes in RxCocoa extensions to enable fluent style
####Fixed

View File

@ -26,7 +26,7 @@ Creating an Observable is one thing, but if nothing subscribes to the observable
example("Empty observable") {
let emptyObservable: Observable<Int> = empty()
let emptySubscriber = emptyObservable >- subscribe { event in
let emptySubscriber = emptyObservable .subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -50,7 +50,7 @@ As you can see, no values are ever sent to the subscriber of an empty observable
example("Never observable") {
let neverObservable: Observable<String> = never()
let neverSubscriber = neverObservable >- subscribe { _ in
let neverSubscriber = neverObservable .subscribe { _ in
print("This block is never called.")
}
}
@ -64,7 +64,7 @@ example("returnElement/just") {
let oneObservable = just(32)
let oneObservableSubscriber = oneObservable
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -81,15 +81,15 @@ Here we see that the `.Next` event is sent just once, then the `.Completed` even
*/
/*:
### returnElements
### sequence
Now we are getting to some more interesting ways to create an Observable. This function creates an observable that produces a number of values before completing.
*/
example("returnElements") {
let multipleObservable/* : Observable<Int> */ = returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
example("sequence") {
let multipleObservable/* : Observable<Int> */ = sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
let multipleObservableSubscriber = multipleObservable
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -114,7 +114,7 @@ example("from") {
let fromArrayObservable = from([1, 2, 3, 4, 5])
let fromArrayObservableSubscriber = fromArrayObservable
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -140,8 +140,8 @@ Up to this point, I have only used the `subscribe` method to listen to Observabl
*/
example("subscribeNext") {
let nextOnlySubscriber = returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>- subscribeNext { value in
let nextOnlySubscriber = sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
.subscribeNext { value in
print("\(value)")
}
}
@ -161,11 +161,11 @@ The most common way to reduce a sequence is to apply a filter to it and the most
*/
example("filter") {
let onlyEvensSubscriber = returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>- filter {
let onlyEvensSubscriber = sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
.filter {
$0 % 2 == 0
}
>- subscribeNext { value in
.subscribeNext { value in
print("\(value)")
}
}
@ -176,9 +176,9 @@ This filter tracks the last value emitted and removes like values. This function
*/
example("distinctUntilChanged") {
let distinctUntilChangedSubscriber = returnElements(1, 2, 3, 1, 1, 4)
>- distinctUntilChanged
>- subscribeNext { value in
let distinctUntilChangedSubscriber = sequence(1, 2, 3, 1, 1, 4)
.distinctUntilChanged
.subscribeNext { value in
print("\(value)")
}
}
@ -197,9 +197,9 @@ This function will perform a function on each element in the sequence until it i
*/
example("aggregate") {
let aggregateSubscriber = returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>- aggregate(0, +)
>- subscribeNext { value in
let aggregateSubscriber = sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
.aggregate(0, +)
.subscribeNext { value in
print("\(value)")
}
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' requires-full-environment='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>
</playground>

View File

@ -20,11 +20,11 @@ Return an observeble which emits a specified item before emitting the items from
example("startWith") {
let aggregateSubscriber = from([4, 5, 6, 7, 8, 9])
>- startWith(3)
>- startWith(2)
>- startWith(1)
>- startWith(0)
>- subscribeNext { int in
.startWith(3)
.startWith(2)
.startWith(1)
.startWith(0)
.subscribeNext { int in
print(int)
}
@ -47,7 +47,7 @@ xample("combineLatest 1st") {
combineLatest(intOb1, intOb2) {
"\($0) \($1)"
}
>- subscribeNext {
.subscribeNext {
print($0)
}
@ -79,7 +79,7 @@ est 2nd") {
combineLatest(intOb1, intOb2) {
$0 * $1
}
>- subscribeNext {
.subscribeNext {
print($0)
}
}
@ -97,7 +97,7 @@ t 3rd") {
combineLatest(intOb1, intOb2, intOb3) {
($0 + $1) * $2
}
>- subscribeNext {
.subscribeNext {
print($0)
}
}
@ -117,7 +117,7 @@ The Observable returned by `zip` emits an item only when all of the imputs Obser
zip(intOb1, intOb2) {
"\($0) \($1)"
}
>- subscribeNext {
.subscribeNext {
print($0)
}
@ -154,7 +154,7 @@ example("zip 2nd") {
zip(intOb1, intOb2) {
$0 * $1
}
>- subscribeNext {
.subscribeNext {
print($0)
}
}
@ -172,7 +172,7 @@ The next sample shows zip called with three sorce Observables
zip(intOb1, intOb2, intOb3) {
($0 + $1) * $2
}
>- subscribeNext {
.subscribeNext {
print($0)
}
}
@ -190,8 +190,8 @@ Combine multiple Observables, of the same type, into one by merging their emissi
Subject<Int>()
let subject2 = PublishSubject<Int>()
merge(returnElements(subject1, subject2))
>- subscribeNext { int in
merge(sequence(subject1, subject2))
.subscribeNext { int in
print(int)
}
@ -209,9 +209,9 @@ example("merge 2nd") {
let subject1 = PublishSubject<Int>()
let subject2 = PublishSubject<Int>()
returnElements(subject1, subject2)
>- merge(maxConcurrent: 2)
>- subscribeNext { int in
sequence(subject1, subject2)
.merge(maxConcurrent: 2)
.subscribeNext { int in
print(int)
}
@ -241,28 +241,25 @@ Convert an Observable that emits Observables into a single Observable that emits
let var3 = Variable(var1 as Observable<Int>)
let d = var3
>- switchLatest
>- subscribeNext { (e: Int) -> Void in
.switchLatest
.subscribeNext { (e: Int) -> Void in
print("\(e)")
}
var1.next(1)
var1.next(2)
var1.next(3)
var1.next(4)
var1.sendNext(1)
var1.sendNext(2)
var1.sendNext(3)
var1.sendNext(4)
var3.next(var2)
var3.sendNext(var2)
var2.next(201)
var2.sendNext(201)
print("Note which no listen to var1")
var1.next(5)
var1.next(6)
var1.next(7)
var1.sendNext(5)
var1.sendNext(6)
var1.sendNext(7)
sendCompleted(var1)
var2.next(202)
var2.next(203)
var2.next(204)
}
var2.sendNext(202)
var2.send

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' requires-full-environment='true' display-mode='rendered'>
<timeline fileName='timeline.xctimeline'/>
</playground>
</playground>

View File

@ -22,8 +22,8 @@ example("takeUntil") {
let observable2 = PublishSubject<Int>()
observable1
>- takeUntil(observable2)
>- subscribeNext { int in
.takeUntil(observable2)
.subscribeNext { int in
print(int)
}
@ -52,10 +52,10 @@ xample("takeWhile") {
let observable1 = PublishSubject<Int>()
observable1
>- takeWhile { int in
.takeWhile { int in
int < 4
}
>- subscribeNext { int in
.subscribeNext { int in
print(int)
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' requires-full-environment='true' display-mode='rendered'>
<timeline fileName='timeline.xctimeline'/>
</playground>
</playground>

View File

@ -18,13 +18,13 @@ func sampleWithoutConnectableOperators() {
let int1 = interval(1, MainScheduler.sharedInstance)
int1
>- subscribeNext {
.subscribeNext {
print("first subscription \($0)")
}
delay(5) {
int1
>- subscribeNext {
.subscribeNext {
print("second subscription \($0)")
}
}
@ -44,15 +44,15 @@ nc sampleWithMulticast() {
let subject1 = PublishSubject<Int64>()
subject1
>- subscribeNext {
.subscribeNext {
print("Subject \($0)")
}
let int1 = interval(1, MainScheduler.sharedInstance)
>- multicast(subject1)
.multicast(subject1)
int1
>- subscribeNext {
.subscribeNext {
print("first subscription \($0)")
}
@ -62,7 +62,7 @@ nc sampleWithMulticast() {
delay(4) {
int1
>- subscribeNext {
.subscribeNext {
print("second subscription \($0)")
print("---")
}
@ -70,7 +70,7 @@ nc sampleWithMulticast() {
delay(6) {
int1
>- subscribeNext {
.subscribeNext {
print("thirth subscription \($0)")
}
}
@ -95,10 +95,10 @@ publish = multicast + replay subject
ithReplayBuffer0() {
let int1 = interval(1, MainScheduler.sharedInstance)
>- replay(0)
.replay(0)
int1
>- subscribeNext {
.subscribeNext {
print("first subscription \($0)")
}
@ -108,7 +108,7 @@ ithReplayBuffer0() {
delay(4) {
int1
>- subscribeNext {
.subscribeNext {
print("second subscription \($0)")
print("---")
}
@ -116,7 +116,7 @@ ithReplayBuffer0() {
delay(6) {
int1
>- subscribeNext {
.subscribeNext {
print("thirth subscription \($0)")
}
}
@ -131,10 +131,10 @@ func sampleWithReplayBuffer2() {
print("--- sampleWithReplayBuffer2 ---\n")
let int1 = interval(1, MainScheduler.sharedInstance)
>- replay(2)
.replay(2)
int1
>- subscribeNext {
.subscribeNext {
print("first subscription \($0)")
}
@ -144,7 +144,7 @@ func sampleWithReplayBuffer2() {
delay(4) {
int1
>- subscribeNext {
.subscribeNext {
print("second subscription \($0)")
print("---")
}
@ -152,7 +152,7 @@ func sampleWithReplayBuffer2() {
delay(6) {
int1
>- subscribeNext {
.subscribeNext {
print("third subscription \($0)")
}
}
@ -178,10 +178,10 @@ so publish is basically replay(0)
*/
let int1 = interval(1, MainScheduler.sharedInstance)
>- publish
.publish
int1
>- subscribeNext {
.subscribeNext {
print("first subscription \($0)")
}
@ -191,7 +191,7 @@ so publish is basically replay(0)
delay(4) {
int1
>- subscribeNext {
.subscribeNext {
print("second subscription \($0)")
print("---")
}
@ -199,7 +199,7 @@ so publish is basically replay(0)
delay(6) {
int1
>- subscribeNext {
.subscribeNext {
print("third subscription \($0)")
}
}

View File

@ -19,7 +19,7 @@ Creates an observable that contains no objects. The only message it sends is the
example("Empty observable") {
let emptyObservable: Observable<Int> = empty()
let emptySubscriber = emptyObservable >- subscribe { event in
let emptySubscriber = emptyObservable .subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -45,7 +45,7 @@ e("Never observable") {
let neverObservable: Observable<String> = never()
let neverSubscriber = neverObservable
>- subscribe { _ in
.subscribe { _ in
print("This block is never called.")
}
}
@ -64,7 +64,7 @@ Creates an observable that contains no objects and send only a error out.
let errorObservable: Observable<Int> = failWith(error)
let errorSubscriber = errorObservable
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -87,7 +87,7 @@ rnElement/just") {
let oneObservable = just(32)
let oneObservableSubscriber = oneObservable
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -105,15 +105,15 @@ Here we see that the `.Next` event is sent just once, then the `.Completed` even
### `returnElements`
### `sequence`
Now we are getting to some more interesting ways to create an Observable. This function creates an observable that produces a number of values before completing.
*/
ents") {
let multipleObservable/* : Observable<Int> */ = returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
let multipleObservable/* : Observable<Int> */ = sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
let multipleObservableSubscriber = multipleObservable
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -139,7 +139,7 @@ We can also create an observable from any SequenceType, such as an array
fromArrayObservable = from([1, 2, 3, 4, 5])
let fromArrayObservableSubscriber = fromArrayObservable
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -171,12 +171,12 @@ int("creating")
}
observable
>- subscribeNext {
.subscribeNext {
print($0)
}
observable
>- subscribeNext {
.subscribeNext {
print($0)
}
}
@ -203,12 +203,12 @@ Create an Observable from a function which create an observable. But do not crea
}
defered
>- subscribeNext {
.subscribeNext {
print($0)
}
defered
>- subscribeNext {
.subscribeNext {
print($0)
}
}

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' requires-full-environment='true' display-mode='rendered'>
<timeline fileName='timeline.xctimeline'/>
</playground>
</playground>

View File

@ -23,10 +23,10 @@ example("catch 1st") {
let observable2 = PublishSubject<Int>()
observable1
>- catch { error in
.catch { error in
return observable2
}
>- subscribe { event in
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -58,8 +58,8 @@ example("catch 2nd") {
let observable1 = PublishSubject<Int>()
observable1
>- catch(100)
>- subscribe { event in
.catch(100)
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")
@ -109,8 +109,8 @@ try") {
}
observable
>- retry
>- subscribe { event in
.retry
.subscribe { event in
switch event {
case .Next(let box):
print("\(box.value)")

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' requires-full-environment='true' display-mode='rendered'>
<timeline fileName='timeline.xctimeline'/>
</playground>
</playground>

View File

@ -18,11 +18,11 @@ emit only those items from an Observable that pass a predicate test
*/
example("filter") {
let onlyEvensSubscriber = returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>- filter {
let onlyEvensSubscriber = sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
.filter {
$0 % 2 == 0
}
>- subscribeNext { value in
.subscribeNext { value in
print("\(value)")
}
}
@ -35,9 +35,9 @@ suppress duplicate items emitted by an Observable
[More info in reactive.io website]( http://reactivex.io/documentation/operators/distinct.html )
*/
xample("distinctUntilChanged") {
let distinctUntilChangedSubscriber = returnElements(1, 2, 3, 1, 1, 4)
>- distinctUntilChanged
>- subscribeNext { value in
let distinctUntilChangedSubscriber = sequence(1, 2, 3, 1, 1, 4)
.distinctUntilChanged
.subscribeNext { value in
print("\(value)")
}
}
@ -50,9 +50,9 @@ Emit only the first n items emitted by an Observable
[More info in reactive.io website]( http://reactivex.io/documentation/operators/take.html )
*/
mple("take") {
let distinctUntilChangedSubscriber = returnElements(1, 2, 3, 4, 5, 6)
>- take(3)
>- subscribeNext { value in
let distinctUntilChangedSubscriber = sequence(1, 2, 3, 4, 5, 6)
.take(3)
.subscribeNext { value in
print("\(value)")
}
}

View File

@ -25,28 +25,28 @@ example("concat") {
let var3 = Variable(var1 as Observable<Int>)
let d = var3
>- concat
>- subscribeNext { (e: Int) -> Void in
.concat
.subscribeNext { (e: Int) -> Void in
print("\(e)")
}
var1.next(1)
var1.next(2)
var1.next(3)
var1.next(4)
var1.sendNext(1)
var1.sendNext(2)
var1.sendNext(3)
var1.sendNext(4)
var3.next(var2)
var3.sendNext(var2)
var2.next(201)
var2.sendNext(201)
var1.next(5)
var1.next(6)
var1.next(7)
var1.sendNext(5)
var1.sendNext(6)
var1.sendNext(7)
sendCompleted(var1)
var2.next(202)
var2.next(203)
var2.next(204)
var2.sendNext(202)
var2.sendNext(203)
var2.sendNext(204)
}
@ -61,9 +61,6 @@ This function will perform a function on each element in the sequence until it i
*/
xample("aggregate") {
let aggregateSubscriber = returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>- aggregate(0, +)
>- subscribeNext { value in
print("\(value)")
}
}
let aggregateSubscriber = sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
.aggregate(0, +)
.subscribeNext { value

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' requires-full-environment='true' display-mode='rendered'>
<timeline fileName='timeline.xctimeline'/>
</playground>
</playground>

View File

@ -28,10 +28,10 @@ example("map") {
}
observable1
>- map { char in
.map { char in
char.hashValue
}
>- subscribeNext { int in
.subscribeNext { int in
print(int)
}
}
@ -65,10 +65,10 @@ xample("flatMap") {
}
observable1
>- flatMap { int in
.flatMap { int in
observable2
}
>- subscribeNext {
.subscribeNext {
print($0)
}
}
@ -94,10 +94,10 @@ mple("scan") {
}
observable
>- scan(0) { acum, elem in
.scan(0) { acum, elem in
acum + elem
}
>- subscribeNext {
.subscribeNext {
print($0)
}
}

View File

@ -21,7 +21,7 @@ example("subscribe") {
let intOb1 = PublishSubject<Int>()
intOb1
>- subscribe { event in
.subscribe { event in
print(event)
}
@ -43,7 +43,7 @@ xample("subscribeNext") {
let intOb1 = PublishSubject<Int>()
intOb1
>- subscribeNext { int in
.subscribeNext { int in
print(int)
}
@ -63,7 +63,7 @@ mple("subscribeCompleted") {
let intOb1 = PublishSubject<Int>()
intOb1
>- subscribeCompleted {
.subscribeCompleted {
print("It's completed")
}
@ -82,7 +82,7 @@ le("subscribeError") {
let intOb1 = PublishSubject<Int>()
intOb1
>- subscribeError { error in
.subscribeError { error in
print(error)
}
@ -103,12 +103,12 @@ Returns the same source Observable but the given closure responsible for the act
let intOb1 = PublishSubject<Int>()
let intOb2 = intOb1
>- `do` { event in
.`do` { event in
print("first \(event)")
}
intOb2
>- subscribeNext { int in
.subscribeNext { int in
print("second \(int)")
}
@ -128,12 +128,12 @@ OnNext") {
let intOb1 = PublishSubject<Int>()
let intOb2 = intOb1
>- doOnNext { int in
.doOnNext { int in
print("first \(int)")
}
intOb2
>- subscribeNext { int in
.subscribeNext { int in
print("second \(int)")
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' requires-full-environment='true' display-mode='rendered'>
<timeline fileName='timeline.xctimeline'/>
</playground>
</playground>

View File

@ -9,20 +9,20 @@ To use playgrounds please open Rx.xcworkspace, build RxSwift-OSX scheme and then
func writeSequenceToConsole(name: String, sequence: Observable<String>) {
sequence
>- subscribeNext {
.subscribeNext {
print("Subscription: \(name), value: \($0)")
}
}
/*:
ex/*:
## PublishSubject
PublishSubject can begin emitting items immediately upon creation, but there is a risk that one or more items may be lost between the time the Subject is created and the observer subscribes to it.
*/
example("PublishSubject") {
ample("PublishSubject") {
let subject = PublishSubject<String>()
writeSequenceToConsole("1", subject)
sendNext(subject, "a")
@ -33,14 +33,14 @@ example("PublishSubject") {
}
/*:
ex/*:
## ReplaySubject
ReplaySubject emits to any observer all of the items, in the buffer, that were emitted by the source
*/
example("ReplaySubject") {
ample("ReplaySubject") {
let subject = ReplaySubject<String>(bufferSize: 1)
writeSequenceToConsole("1", subject)
sendNext(subject, "a")
@ -51,14 +51,14 @@ example("ReplaySubject") {
}
/*:
ex/*:
## BehaviorSubject a.k.a. Variable
ReplaySubject emits to any observer all of the items, in the buffer, that were emitted by the source
*/
example("ReplaySubject") {
ample("ReplaySubject") {
let subject = BehaviorSubject(value: "z")
writeSequenceToConsole("1", subject)
sendNext(subject, "a")

View File

@ -81,11 +81,11 @@ let files = fileManager.subpathsAtPath(sourceFilesRoot)
var generateAllFiles = ["// Generated code\n", "import Foundation\n"]
for file in files! {
if (file.pathExtension ?? "") != "tt" {
if ((file as NSString).pathExtension ?? "") != "tt" {
continue
}
let path = sourceFilesRoot.stringByAppendingPathComponent(file as String)
let path = (sourceFilesRoot as NSString).stringByAppendingPathComponent(file as String)
let outputPath = path.substringToIndex(path.endIndex.predecessor().predecessor().predecessor()) + ".swift"
@ -93,7 +93,7 @@ for file in files! {
}
let script = "".join(generateAllFiles)
let scriptPath = derivedData.stringByAppendingPathComponent("_preprocessor.sh")
let scriptPath = (derivedData as NSString).stringByAppendingPathComponent("_preprocessor.sh")
do {
try script.writeToFile(scriptPath, atomically: true, encoding: NSUTF8StringEncoding)

View File

@ -85,8 +85,8 @@ These are so called bindings and Rx can help you model your system that way.
```swift
combineLatest(firstName.rx_text, lastName.rx_text) { $0 + " " + $1 }
>- map { "Greeting \($0)" }
>- subscribeNext { greeting in
.map { "Greeting \($0)" }
.subscribeNext { greeting in
greetingLabel.text = greeting
}
```
@ -107,7 +107,7 @@ This is how you can do simple retries with Rx
```swift
doSomethingIncredible("me")
>- retry(3)
.retry(3)
```
You can also easily create custom retry operators.
@ -128,16 +128,16 @@ Writing all of this and properly testing it would be tedious. This is that same
```swift
searchTextField.rx_text
>- throttle(0.3, MainScheduler.sharedInstance)
>- distinctUntilChanged
>- map { query in
.throttle(0.3, MainScheduler.sharedInstance)
.distinctUntilChanged
.map { query in
API.getSearchResults(query)
>- retry(3)
>- startWith([]) // clears results on new search term
>- catch([])
.retry(3)
.startWith([]) // clears results on new search term
.catch([])
}
>- switchLatest
>- map { results in
.switchLatest
.map { results in
// bind to ui
}
```
@ -157,7 +157,7 @@ Well, there is of course `zip` operator
zip(userRequest, friendsRequest) { user, friends in
return (user, friends)
}
>- subscribeNext { user, friends in
.subscribeNext { user, friends in
// bind them to user interface
}
```
@ -171,8 +171,8 @@ So what if those APIs return results on a background thread, and binding has to
zip(userRequest, friendsRequest) { user, friends in
return (user, friends)
}
>- observeOn(MainScheduler.sharedInstance)
>- subscribeNext { user, friends in
.observeOn(MainScheduler.sharedInstance)
.subscribeNext { user, friends in
// bind them to user interface
}
```
@ -221,16 +221,16 @@ This is how we can do it using Rx.
```swift
let imageSubscripton = just(imageURL)
>- throttle(0.2, MainScheduler.sharedInstance)
>- flatMap { imageURL in
.throttle(0.2, MainScheduler.sharedInstance)
.flatMap { imageURL in
API.fetchImage(imageURL)
}
>- observeOn(operationScheduler)
>- map { imageData in
.observeOn(operationScheduler)
.map { imageData in
return decodeAndBlurImage(imageData)
}
>- observeOn(MainScheduler.sharedInstance)
>- subscribeNext { blurredImage in
.observeOn(MainScheduler.sharedInstance)
.subscribeNext { blurredImage in
imageView.image = blurredImage
}
@ -272,10 +272,10 @@ extension UISearchBar {
let text = self?.text ?? ""
return self?.rx_delegate.observe("searchBar:textDidChange:") ?? empty()
>- map { a in
.map { a in
return a[1] as? String ?? ""
}
>- startWith(text)
.startWith(text)
}
}
}
@ -288,7 +288,7 @@ This is how that API can be now used
```swift
searchBar.rx_searchText
>- subscribeNext { searchText in
.subscribeNext { searchText in
print("Current search text '\(searchText)'")
}
@ -344,7 +344,7 @@ This is how they can be used:
```swift
view.rx_observe("frame")
>- subscribeNext { (frame: CGRect?) in
.subscribeNext { (frame: CGRect?) in
print("Got new frame \(frame)")
}
```
@ -353,7 +353,7 @@ or
```swift
someSuspiciousViewController.rx_observeWeakly("behavingOk")
>- subscribeNext { (behavingOk: Bool?) in
.subscribeNext { (behavingOk: Bool?) in
print("Cats can purr? \(behavingOk)")
}
```

View File

@ -11,130 +11,134 @@ import Foundation
import RxSwift
#endif
public func toArray<E>(source: Observable<E>)
-> RxResult<[E]> {
let condition = NSCondition()
var elements = [E]()
var error: ErrorType?
extension ObservableType {
public func toArray()
-> RxResult<[E]> {
let condition = NSCondition()
var ended = false
var elements = [E]()
var error: ErrorType?
var ended = false
source.subscribeSafe(AnonymousObserver { e in
switch e {
case .Next(let element):
elements.append(element)
case .Error(let e):
error = e
condition.lock()
ended = true
condition.signal()
condition.unlock()
case .Completed:
condition.lock()
ended = true
condition.signal()
condition.unlock()
}
})
condition.lock()
while !ended {
condition.wait()
}
condition.unlock()
if let error = error {
return failure(error)
}
return success(elements)
}
public func first<E>(source: Observable<E>)
-> RxResult<E?> {
let condition = NSCondition()
var element: E?
var error: ErrorType?
var ended = false
let d = SingleAssignmentDisposable()
d.disposable = source.subscribeSafe(AnonymousObserver { e in
switch e {
case .Next(let e):
if element == nil {
element = e
self.subscribeSafe(AnonymousObserver { e in
switch e {
case .Next(let element):
elements.append(element)
case .Error(let e):
error = e
condition.lock()
ended = true
condition.signal()
condition.unlock()
case .Completed:
condition.lock()
ended = true
condition.signal()
condition.unlock()
}
break
case .Error(let e):
error = e
default:
break
}
})
condition.lock()
ended = true
condition.signal()
while !ended {
condition.wait()
}
condition.unlock()
})
condition.lock()
while !ended {
condition.wait()
if let error = error {
return failure(error)
}
return success(elements)
}
d.dispose()
condition.unlock()
if let error = error {
return failure(error)
}
return success(element)
}
public func last<E>(source: Observable<E>)
-> RxResult<E?> {
let condition = NSCondition()
var element: E?
var error: ErrorType?
var ended = false
let d = SingleAssignmentDisposable()
d.disposable = source.subscribeSafe(AnonymousObserver { e in
switch e {
case .Next(let e):
element = e
return
case .Error(let e):
error = e
default:
break
}
extension ObservableType {
public var first: RxResult<E?> {
let condition = NSCondition()
var element: E?
var error: ErrorType?
var ended = false
let d = SingleAssignmentDisposable()
d.disposable = self.subscribeSafe(AnonymousObserver { e in
switch e {
case .Next(let e):
if element == nil {
element = e
}
break
case .Error(let e):
error = e
default:
break
}
condition.lock()
ended = true
condition.signal()
condition.unlock()
})
condition.lock()
ended = true
condition.signal()
while !ended {
condition.wait()
}
d.dispose()
condition.unlock()
})
condition.lock()
while !ended {
condition.wait()
if let error = error {
return failure(error)
}
return success(element)
}
d.dispose()
condition.unlock()
if let error = error {
return failure(error)
}
extension ObservableType {
public var last: RxResult<E?> {
let condition = NSCondition()
var element: E?
var error: ErrorType?
var ended = false
let d = SingleAssignmentDisposable()
d.disposable = self.subscribeSafe(AnonymousObserver { e in
switch e {
case .Next(let e):
element = e
return
case .Error(let e):
error = e
default:
break
}
condition.lock()
ended = true
condition.signal()
condition.unlock()
})
condition.lock()
while !ended {
condition.wait()
}
d.dispose()
condition.unlock()
if let error = error {
return failure(error)
}
return success(element)
}
return success(element)
}

View File

@ -149,7 +149,7 @@
C88BB88D1B07E6130064D411 /* RxCocoa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C88BB8E01B07F2BE0064D411 /* UIButton+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIButton+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C88BB8E11B07F2BE0064D411 /* UICollectionView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UICollectionView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C88BB8E21B07F2BE0064D411 /* UIImageView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIImageView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C88BB8E21B07F2BE0064D411 /* UIImageView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIImageView+Rx.swift"; sourceTree = "<group>"; };
C88BB8E31B07F2BE0064D411 /* UILabel+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UILabel+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C88BB8E41B07F2BE0064D411 /* UIScrollView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIScrollView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C88BB8E51B07F2BE0064D411 /* UISearchBar+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UISearchBar+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
@ -165,7 +165,7 @@
C8CDD7D81B52DA570043F0C5 /* RxCLLocationManagerDelegateProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = RxCLLocationManagerDelegateProxy.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8CDD7DB1B52DA790043F0C5 /* CLLocationManager+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "CLLocationManager+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8CDD7DE1B52DAA80043F0C5 /* RxTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = RxTarget.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8D95C161B2F0CD700FA661F /* DelegateProxyType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DelegateProxyType.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8D95C161B2F0CD700FA661F /* DelegateProxyType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DelegateProxyType.swift; sourceTree = "<group>"; };
CBEEA6781B12323800176529 /* NSSlider+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "NSSlider+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
F333C2E91B5AF33E00F1D8D9 /* UITextView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UITextView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
F333C2EB1B5AF35400F1D8D9 /* RxTextViewDelegateProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = RxTextViewDelegateProxy.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };

View File

@ -22,21 +22,21 @@ extension CLLocationManager {
public var rx_didUpdateLocations: Observable<[CLLocation]!> {
return rx_delegate.observe("locationManager:didUpdateLocations:")
>- map { a in
.map { a in
return a[1] as? [CLLocation]
}
}
public var rx_didFailWithError: Observable<NSError!> {
return rx_delegate.observe("locationManager:didFailWithError:")
>- map { a in
.map { a in
return a[1] as? NSError
}
}
public var rx_didFinishDeferredUpdatesWithError: Observable<NSError!> {
return rx_delegate.observe("locationManager:didFinishDeferredUpdatesWithError:")
>- map { a in
.map { a in
return a[1] as? NSError
}
}
@ -45,14 +45,14 @@ extension CLLocationManager {
public var rx_didPauseLocationUpdates: Observable<Void> {
return rx_delegate.observe("locationManagerDidPauseLocationUpdates:")
>- map { _ in
.map { _ in
return ()
}
}
public var rx_didResumeLocationUpdates: Observable<Void> {
return rx_delegate.observe("locationManagerDidResumeLocationUpdates:")
>- map { _ in
.map { _ in
return ()
}
}
@ -61,7 +61,7 @@ extension CLLocationManager {
public var rx_didUpdateHeading: Observable<CLHeading!> {
return rx_delegate.observe("locationManager:didUpdateHeading:")
>- map { a in
.map { a in
return a[1] as? CLHeading
}
}
@ -70,35 +70,35 @@ extension CLLocationManager {
public var rx_didEnterRegion: Observable<CLRegion!> {
return rx_delegate.observe("locationManager:didEnterRegion:")
>- map { a in
.map { a in
return a[1] as? CLRegion
}
}
public var rx_didExitRegion: Observable<CLRegion!> {
return rx_delegate.observe("locationManager:didExitRegion:")
>- map { a in
.map { a in
return a[1] as? CLRegion
}
}
public var rx_didDetermineStateForRegion: Observable<(state: CLRegionState, region: CLRegion!)> {
return rx_delegate.observe("locationManager:didDetermineState:forRegion:")
>- map { a in
.map { a in
return (state: a[1] as! CLRegionState, region: a[2] as? CLRegion)
}
}
public var rx_monitoringDidFailForRegionWithError: Observable<(region: CLRegion!, error: NSError!)> {
return rx_delegate.observe("locationManager:monitoringDidFailForRegion:withError:")
>- map { a in
.map { a in
return (region: a[1] as? CLRegion, error: a[2] as? NSError)
}
}
public var rx_didStartMonitoringForRegion: Observable<CLRegion!> {
return rx_delegate.observe("locationManager:didStartMonitoringForRegion:")
>- map { a in
.map { a in
return a[1] as? CLRegion
}
}
@ -109,14 +109,14 @@ extension CLLocationManager {
public var rx_didRangeBeaconsInRegion: Observable<(beacons: [CLBeacon]!, region: CLBeaconRegion!)> {
return rx_delegate.observe("locationManager:didRangeBeacons:inRegion:")
>- map { a in
.map { a in
return (beacons: a[1] as? [CLBeacon], region: a[2] as? CLBeaconRegion)
}
}
public var rx_rangingBeaconsDidFailForRegionWithError: Observable<(region: CLBeaconRegion!, error: NSError!)> {
return rx_delegate.observe("locationManager:rangingBeaconsDidFailForRegion:withError:")
>- map { a in
.map { a in
return (region: a[1] as? CLBeaconRegion, error: a[2] as? NSError)
}
}
@ -126,7 +126,7 @@ extension CLLocationManager {
@available(iOS 8.0, *)
public var rx_didVisit: Observable<CLVisit!> {
return rx_delegate.observe("locationManager:didVisit:")
>- map { a in
.map { a in
return a[1] as? CLVisit
}
}
@ -137,7 +137,7 @@ extension CLLocationManager {
public var rx_didChangeAuthorizationStatus: Observable<CLAuthorizationStatus> {
return rx_delegate.observe("locationManager:didChangeAuthorizationStatus:")
>- map { a in
.map { a in
return a[1] as! CLAuthorizationStatus
}
}

View File

@ -153,14 +153,15 @@ func installDelegate<P: DelegateProxyType>(proxy: P, delegate: AnyObject, retain
}
}
func setProxyDataSourceForObject<P: DelegateProxyType, Element>(object: AnyObject, dataSource: AnyObject, retainDataSource: Bool, binding: (P, Event<Element>) -> Void)
-> Observable<Element> -> Disposable {
return { source in
extension ObservableType {
func subscribeProxyDataSourceForObject<P: DelegateProxyType>(object: AnyObject, dataSource: AnyObject, retainDataSource: Bool, binding: (P, Event<E>) -> Void)
-> Disposable {
let proxy: P = proxyForObject(object)
let disposable = installDelegate(proxy, delegate: dataSource, retainDelegate: retainDataSource, onProxyForObject: object)
// we should never let the subscriber to complete because it should retain data source
let subscription = concat(returnElements(source, never())).subscribe(AnonymousObserver { event in
let source = sequence(self.normalize(), never()) as Observable<Observable<E>>
let subscription = source.concat.subscribe { (event: Event<E>) in
MainScheduler.ensureExecutingOnScheduler()
assert(proxy === P.currentDelegateFor(object), "Proxy changed from the time it was first set.\nOriginal: \(proxy)\nExisting: \(P.currentDelegateFor(object))")
@ -178,7 +179,7 @@ func setProxyDataSourceForObject<P: DelegateProxyType, Element>(object: AnyObjec
default:
break
}
})
}
return StableCompositeDisposable.create(subscription, disposable)
}

View File

@ -52,15 +52,15 @@ func observeWeaklyKeyPathFor(target: NSObject, keyPath: String, options: NSKeyVa
let components = keyPath.componentsSeparatedByString(".").filter { $0 != "self" }
let observable = observeWeaklyKeyPathFor(target, keyPathSections: components, options: options)
>- distinctUntilChanged { $0 === $1 }
>- finishWithNilWhenDealloc(target)
.distinctUntilChanged { $0 === $1 }
.finishWithNilWhenDealloc(target)
if !options.intersect(.Initial).isEmpty {
return observable
}
else {
return observable
>- skip(1)
.skip(1)
}
}
@ -72,17 +72,17 @@ func isWeakProperty(properyRuntimeInfo: String) -> Bool {
return properyRuntimeInfo.rangeOfString(",W,") != nil
}
func finishWithNilWhenDealloc(target: NSObject)
-> Observable<AnyObject?> -> Observable<AnyObject?> {
let deallocating = target.rx_deallocating
return { source in
extension ObservableType where E == AnyObject? {
func finishWithNilWhenDealloc(target: NSObject)
-> Observable<AnyObject?> {
let deallocating = target.rx_deallocating
return deallocating
>- map { _ in
.map { _ in
return just(nil)
}
>- startWith(source)
>- switchLatest
.startWith(self.normalize())
.switchLatest
}
}
@ -109,7 +109,7 @@ func observeWeaklyKeyPathFor(
// KVO recursion for value changes
return propertyObservable
>- map { (nextTarget: AnyObject?) in
.map { (nextTarget: AnyObject?) -> Observable<AnyObject?> in
if nextTarget == nil {
return just(nil)
}
@ -133,13 +133,13 @@ func observeWeaklyKeyPathFor(
if isWeak {
return nextElementsObservable
>- finishWithNilWhenDealloc(nextObject!)
.finishWithNilWhenDealloc(nextObject!)
}
else {
return nextElementsObservable
}
}
>- switchLatest
.switchLatest
}
#endif

View File

@ -25,8 +25,8 @@ let CGPointType = "{CGPoint=ff}"
// rx_observe + CoreGraphics
extension NSObject {
public func rx_observe(keyPath: String, options: NSKeyValueObservingOptions = NSKeyValueObservingOptions.New.union(NSKeyValueObservingOptions.Initial), retainSelf: Bool = true) -> Observable<CGRect?> {
return rx_observe(keyPath, options: options, retainSelf: retainSelf) as Observable<NSValue?>
>- map { value in
return rx_observe(keyPath, options: options, retainSelf: retainSelf)
.map { (value: NSValue?) in
if let value = value {
if strcmp(value.objCType, CGRectType) != 0 {
return nil
@ -42,8 +42,8 @@ extension NSObject {
}
public func rx_observe(keyPath: String, options: NSKeyValueObservingOptions = NSKeyValueObservingOptions.New.union(NSKeyValueObservingOptions.Initial), retainSelf: Bool = true) -> Observable<CGSize?> {
return rx_observe(keyPath, options: options, retainSelf: retainSelf) as Observable<NSValue?>
>- map { value in
return rx_observe(keyPath, options: options, retainSelf: retainSelf)
.map { (value: NSValue?) in
if let value = value {
if strcmp(value.objCType, CGSizeType) != 0 {
return nil
@ -59,8 +59,8 @@ extension NSObject {
}
public func rx_observe(keyPath: String, options: NSKeyValueObservingOptions = NSKeyValueObservingOptions.New.union(NSKeyValueObservingOptions.Initial), retainSelf: Bool = true) -> Observable<CGPoint?> {
return rx_observe(keyPath, options: options, retainSelf: retainSelf) as Observable<NSValue?>
>- map { value in
return rx_observe(keyPath, options: options, retainSelf: retainSelf)
.map { (value: NSValue?) in
if let value = value {
if strcmp(value.objCType, CGPointType) != 0 {
return nil
@ -81,8 +81,8 @@ extension NSObject {
// rx_observeWeakly + CoreGraphics
extension NSObject {
public func rx_observeWeakly(keyPath: String, options: NSKeyValueObservingOptions = NSKeyValueObservingOptions.New.union(NSKeyValueObservingOptions.Initial)) -> Observable<CGRect?> {
return rx_observeWeakly(keyPath, options: options) as Observable<NSValue?>
>- map { value in
return rx_observeWeakly(keyPath, options: options)
.map { (value: NSValue?) in
if let value = value {
if strcmp(value.objCType, CGRectType) != 0 {
return nil
@ -98,8 +98,8 @@ extension NSObject {
}
public func rx_observeWeakly(keyPath: String, options: NSKeyValueObservingOptions = NSKeyValueObservingOptions.New.union(NSKeyValueObservingOptions.Initial)) -> Observable<CGSize?> {
return rx_observeWeakly(keyPath, options: options) as Observable<NSValue?>
>- map { value in
return rx_observeWeakly(keyPath, options: options)
.map { (value: NSValue?) in
if let value = value {
if strcmp(value.objCType, CGSizeType) != 0 {
return nil
@ -115,8 +115,8 @@ extension NSObject {
}
public func rx_observeWeakly(keyPath: String, options: NSKeyValueObservingOptions = NSKeyValueObservingOptions.New.union(NSKeyValueObservingOptions.Initial)) -> Observable<CGPoint?> {
return rx_observeWeakly(keyPath, options: options) as Observable<NSValue?>
>- map { value in
return rx_observeWeakly(keyPath, options: options)
.map { (value: NSValue?) in
if let value = value {
if strcmp(value.objCType, CGPointType) != 0 {
return nil

View File

@ -56,7 +56,7 @@ extension NSObject {
// Doesn't retain `self` and when `self` is deallocated, completes the sequence.
public func rx_observeWeakly<Element>(keyPath: String, options: NSKeyValueObservingOptions = NSKeyValueObservingOptions.New.union(NSKeyValueObservingOptions.Initial)) -> Observable<Element?> {
return observeWeaklyKeyPathFor(self, keyPath: keyPath, options: options)
>- map { n in
.map { n in
return n as? Element
}
}

View File

@ -100,7 +100,7 @@ extension NSURLSession {
}
public func rx_data(request: NSURLRequest) -> Observable<NSData> {
return rx_response(request) >- mapOrDie { (data, response) -> RxResult<NSData> in
return rx_response(request).mapOrDie { (data, response) -> RxResult<NSData> in
if let response = response as? NSHTTPURLResponse {
if 200 ..< 300 ~= response.statusCode {
return success(data!)
@ -118,7 +118,7 @@ extension NSURLSession {
}
public func rx_JSON(request: NSURLRequest) -> Observable<AnyObject!> {
return rx_data(request) >- mapOrDie { (data) -> RxResult<AnyObject!> in
return rx_data(request).mapOrDie { (data) -> RxResult<AnyObject!> in
do {
let result = try NSJSONSerialization.JSONObjectWithData(data, options: [])
return success(result)

View File

@ -41,6 +41,26 @@ class RxTextFieldDelegate : DelegateProxy
}
}
extension ObservableType where E == String {
public func subscribeTextOf(textField: NSTextField) -> Disposable {
return self.subscribe { event in
MainScheduler.ensureExecutingOnScheduler()
switch event {
case .Next(let value):
textField.stringValue = value
case .Error(let error):
#if DEBUG
rxFatalError("Binding error to textbox: \(error)")
#endif
break
case .Completed:
break
}
}
}
}
extension NSTextField {
public func rx_subscribeTextTo(source: Observable<String>) -> Disposable {
return source.subscribe(AnonymousObserver { event in

View File

@ -36,16 +36,36 @@ class _RxCollectionViewReactiveArrayDataSource: NSObject, UICollectionViewDataSo
}
}
class RxCollectionViewReactiveArrayDataSourceSequenceWrapper<S: SequenceType> : RxCollectionViewReactiveArrayDataSource<S.Generator.Element>
, RxCollectionViewDataSourceType {
typealias Element = S
override init(cellFactory: CellFactory) {
super.init(cellFactory: cellFactory)
}
func collectionView(collectionView: UICollectionView, observedEvent: Event<S>) {
switch observedEvent {
case .Next(let value):
super.collectionView(collectionView, observedElements: Array(value))
self.itemModels = Array(value)
case .Error(let error):
bindingErrorToInterface(error)
case .Completed:
break
}
}
}
// Please take a look at `DelegateProxyType.swift`
class RxCollectionViewReactiveArrayDataSource<ElementType> : _RxCollectionViewReactiveArrayDataSource
, RxCollectionViewDataSourceType {
typealias Element = [ElementType]
class RxCollectionViewReactiveArrayDataSource<Element> : _RxCollectionViewReactiveArrayDataSource {
typealias CellFactory = (UICollectionView, Int, ElementType) -> UICollectionViewCell
typealias CellFactory = (UICollectionView, Int, Element) -> UICollectionViewCell
var itemModels: [ElementType]? = nil
var itemModels: [Element]? = nil
func modelAtIndex(index: Int) -> ElementType? {
func modelAtIndex(index: Int) -> Element? {
return itemModels?[index]
}
@ -67,15 +87,8 @@ class RxCollectionViewReactiveArrayDataSource<ElementType> : _RxCollectionViewRe
// reactive
func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) {
switch observedEvent {
case .Next(let value):
self.itemModels = value
case .Error(let error):
bindingErrorToInterface(error)
case .Completed:
break
}
func collectionView(collectionView: UICollectionView, observedElements: [Element]) {
self.itemModels = observedElements
collectionView.reloadData()
}

View File

@ -36,16 +36,34 @@ class _RxTableViewReactiveArrayDataSource: NSObject, UITableViewDataSource {
}
}
class RxTableViewReactiveArrayDataSourceSequenceWrapper<S: SequenceType> : RxTableViewReactiveArrayDataSource<S.Generator.Element>
, RxTableViewDataSourceType {
typealias Element = S
override init(cellFactory: CellFactory) {
super.init(cellFactory: cellFactory)
}
func tableView(tableView: UITableView, observedEvent: Event<S>) {
switch observedEvent {
case .Next(let value):
super.tableView(tableView, observedElements: Array(value))
case .Error(let error):
bindingErrorToInterface(error)
case .Completed:
break
}
}
}
// Please take a look at `DelegateProxyType.swift`
class RxTableViewReactiveArrayDataSource<ElementType> : _RxTableViewReactiveArrayDataSource
, RxTableViewDataSourceType {
typealias Element = [ElementType]
class RxTableViewReactiveArrayDataSource<Element> : _RxTableViewReactiveArrayDataSource {
typealias CellFactory = (UITableView, Int, Element) -> UITableViewCell
typealias CellFactory = (UITableView, Int, ElementType) -> UITableViewCell
var itemModels: [Element]? = nil
var itemModels: [ElementType]? = nil
func modelAtIndex(index: Int) -> ElementType? {
func modelAtIndex(index: Int) -> Element? {
return itemModels?[index]
}
@ -65,15 +83,8 @@ class RxTableViewReactiveArrayDataSource<ElementType> : _RxTableViewReactiveArra
// reactive
func tableView(tableView: UITableView, observedEvent: Event<[ElementType]>) {
switch observedEvent {
case .Next(let value):
self.itemModels = value
case .Error(let error):
bindingErrorToInterface(error)
case .Completed:
break
}
func tableView(tableView: UITableView, observedElements: [Element]) {
self.itemModels = observedElements
tableView.reloadData()
}

View File

@ -20,21 +20,21 @@ extension UIActionSheet {
public var rx_clickedButtonAtIndex: Observable<Int> {
return rx_delegate.observe("actionSheet:clickedButtonAtIndex:")
>- map { a in
.map { a in
return a[1] as! Int
}
}
public var rx_willDismissWithButtonIndex: Observable<Int> {
return rx_delegate.observe("actionSheet:willDismissWithButtonIndex:")
>- map { a in
.map { a in
return a[1] as! Int
}
}
public var rx_didDismissWithButtonIndex: Observable<Int> {
return rx_delegate.observe("actionSheet:didDismissWithButtonIndex:")
>- map { a in
.map { a in
return a[1] as! Int
}
}

View File

@ -20,21 +20,21 @@ extension UIAlertView {
public var rx_clickedButtonAtIndex: Observable<Int> {
return rx_delegate.observe("alertView:clickedButtonAtIndex:")
>- map { a in
.map { a in
return a[1] as! Int
}
}
public var rx_willDismissWithButtonIndex: Observable<Int> {
return rx_delegate.observe("alertView:willDismissWithButtonIndex:")
>- map { a in
.map { a in
return a[1] as! Int
}
}
public var rx_didDismissWithButtonIndex: Observable<Int> {
return rx_delegate.observe("alertView:didDismissWithButtonIndex:")
>- map { a in
.map { a in
return a[1] as! Int
}
}

View File

@ -19,7 +19,7 @@ extension UIBarButtonItem {
sendNext(observer, ())
}
return target
} >- takeUntil(rx_deallocated)
} .takeUntil(rx_deallocated)
}
}

View File

@ -12,6 +12,48 @@ import RxSwift
#endif
import UIKit
extension ObservableType {
// data source
// Registers reactive data source with collection view.
// Difference between reactive data source and UICollectionViewDataSource is that reactive
// has additional method:
//
// ```
// func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) -> Void
// ```
//
// If you want to register non reactive data source, please use `rx_setDataSource` method
public func subscribe<DataSource: protocol<RxCollectionViewDataSourceType, UICollectionViewDataSource> where E == DataSource.Element>(collectionView: UICollectionView, withReactiveDataSource dataSource: DataSource)
-> Disposable {
return self.subscribeProxyDataSourceForObject(collectionView, dataSource: dataSource, retainDataSource: false) { (_: RxCollectionViewDataSourceProxy, event) -> Void in
dataSource.collectionView(collectionView, observedEvent: event)
}
}
}
extension ObservableType where E: SequenceType {
// `reloadData` - items subscription methods (it's assumed that there is one section, and it is typed `Void`)
public func subscribeItemsOf(collectionView: UICollectionView, cellFactory: (UICollectionView, Int, E.Generator.Element) -> UICollectionViewCell)
-> Disposable {
let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper<E>(cellFactory: cellFactory)
return self.subscribe(collectionView, withReactiveDataSource: dataSource)
}
public func subscribeItemsOf<Cell: UICollectionViewCell>(collectionView: UICollectionView, withCellIdentifier cellIdentifier: String, configureCell: (Int, E.Generator.Element, Cell) -> Void)
-> Disposable {
let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper<E> { (cv, i, item) in
let indexPath = NSIndexPath(forItem: i, inSection: 0)
let cell = cv.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath) as! Cell
configureCell(i, item, cell)
return cell
}
return self.subscribe(collectionView, withReactiveDataSource: dataSource)
}
}
extension UICollectionView {
// factories
@ -34,57 +76,12 @@ extension UICollectionView {
let proxy: RxCollectionViewDataSourceProxy = proxyForObject(self)
return installDelegate(proxy, delegate: dataSource, retainDelegate: false, onProxyForObject: self)
}
// data source
// Registers reactive data source with collection view.
// Difference between reactive data source and UICollectionViewDataSource is that reactive
// has additional method:
//
// ```
// func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) -> Void
// ```
//
// If you want to register non reactive data source, please use `rx_setDataSource` method
public func rx_subscribeWithReactiveDataSource<DataSource: protocol<RxCollectionViewDataSourceType, UICollectionViewDataSource>>
(dataSource: DataSource)
-> Observable<DataSource.Element> -> Disposable {
return setProxyDataSourceForObject(self, dataSource: dataSource, retainDataSource: false) { (_: RxCollectionViewDataSourceProxy, event) -> Void in
dataSource.collectionView(self, observedEvent: event)
}
}
// `reloadData` - items subscription methods (it's assumed that there is one section, and it is typed `Void`)
public func rx_subscribeItemsTo<Item>
(cellFactory: (UICollectionView, Int, Item) -> UICollectionViewCell)
-> Observable<[Item]> -> Disposable {
return { source in
let dataSource = RxCollectionViewReactiveArrayDataSource<Item>(cellFactory: cellFactory)
return self.rx_subscribeWithReactiveDataSource(dataSource)(source)
}
}
public func rx_subscribeItemsToWithCellIdentifier<Item, Cell: UICollectionViewCell>
(cellIdentifier: String, configureCell: (Int, Item, Cell) -> Void)
-> Observable<[Item]> -> Disposable {
return { source in
let dataSource = RxCollectionViewReactiveArrayDataSource<Item> { (cv, i, item) in
let indexPath = NSIndexPath(forItem: i, inSection: 0)
let cell = cv.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath) as! Cell
configureCell(i, item, cell)
return cell
}
return self.rx_subscribeWithReactiveDataSource(dataSource)(source)
}
}
// events
public var rx_itemSelected: Observable<NSIndexPath> {
return rx_delegate.observe("collectionView:didSelectItemAtIndexPath:")
>- map { a in
.map { a in
return a[1] as! NSIndexPath
}
}
@ -92,38 +89,10 @@ extension UICollectionView {
// typed events
public func rx_modelSelected<T>() -> Observable<T> {
return rx_itemSelected >- map { indexPath in
return rx_itemSelected .map { indexPath in
let dataSource: RxCollectionViewReactiveArrayDataSource<T> = castOrFatalError(self.rx_dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx_subscribeItemsTo` methods was used.")
return dataSource.modelAtIndex(indexPath.item)!
}
}
}
// deprecated
extension UICollectionView {
@available(*, deprecated=1.7, message="Replaced by `rx_subscribeItemsToWithCellIdentifier`")
public func rx_subscribeItemsWithIdentifierTo<E, Cell where E : AnyObject, Cell : UICollectionViewCell>
(cellIdentifier: String, configureCell: (UICollectionView, NSIndexPath, E, Cell) -> Void)
(source: Observable<[E]>)
-> Disposable {
let l = rx_subscribeItemsToWithCellIdentifier(cellIdentifier) { (i: Int, e: E, cell: Cell) in
return configureCell(self, NSIndexPath(forItem: i, inSection: 0), e, cell)
}
return l(source)
}
@available(*, deprecated=1.7, message="Replaced by `rx_itemSelected`")
public func rx_itemTap() -> Observable<(UICollectionView, Int)> {
return rx_itemSelected
>- map { i in
return (self, i.item)
}
}
@available(*, deprecated=1.7, message="Replaced by `rx_modelSelected`")
public func rx_elementTap<E>() -> Observable<E> {
return rx_modelSelected()
}
}

View File

@ -12,6 +12,27 @@ import RxSwift
#endif
import UIKit
extension ObservableType where E == Bool {
public func subscribeEnabledOf(control: UIControl) -> Disposable {
weak var weakControl: UIControl? = control
return self.subscribe { event in
MainScheduler.ensureExecutingOnScheduler()
switch event {
case .Next(let value):
weakControl?.enabled = value
case .Error(let error):
#if DEBUG
rxFatalError("Binding error to textbox: \(error)")
#endif
break
case .Completed:
break
}
}
}
}
extension UIControl {
public func rx_controlEvents(controlEvents: UIControlEvents) -> Observable<Void> {
return AnonymousObservable { observer in
@ -25,7 +46,7 @@ extension UIControl {
return AnonymousDisposable {
controlTarget.dispose()
}
} >- takeUntil(rx_deallocated)
} .takeUntil(rx_deallocated)
}
func rx_value<T>(getValue: () -> T) -> Observable<T> {
@ -40,24 +61,7 @@ extension UIControl {
return AnonymousDisposable {
controlTarget.dispose()
}
} >- takeUntil(rx_deallocated)
} .takeUntil(rx_deallocated)
}
public func rx_subscribeEnabledTo(source: Observable<Bool>) -> Disposable {
return source.subscribe(AnonymousObserver { [weak self] event in
MainScheduler.ensureExecutingOnScheduler()
switch event {
case .Next(let value):
self?.enabled = value
case .Error(let error):
#if DEBUG
rxFatalError("Binding error to textbox: \(error)")
#endif
break
case .Completed:
break
}
})
}
}

View File

@ -61,7 +61,7 @@ extension UIGestureRecognizer {
}
return observer
} >- takeUntil(rx_deallocated)
} .takeUntil(rx_deallocated)
}
}

View File

@ -12,39 +12,38 @@ import RxSwift
#endif
import UIKit
extension UIImageView {
public func rx_subscribeImageTo(source: Observable<UIImage?>) -> Disposable {
return rx_subscribeImageTo(false)(source)
extension ObservableType where E == UIImage? {
public func subscribeImageOf(imageView: UIImageView) -> Disposable {
return subscribeImageOf(imageView, animated: false)
}
public func rx_subscribeImageTo
(animated: Bool)
-> Observable<UIImage?> -> Disposable {
return { source in
return source.subscribe(AnonymousObserver { event in
MainScheduler.ensureExecutingOnScheduler()
switch event {
case .Next(let boxedValue):
let value = boxedValue
if animated && value != nil {
let transition = CATransition()
transition.duration = 0.25
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
self.layer.addAnimation(transition, forKey: kCATransition)
}
else {
self.layer.removeAllAnimations()
}
self.image = value
case .Error(let error):
bindingErrorToInterface(error)
break
case .Completed:
break
public func subscribeImageOf(imageView: UIImageView, animated: Bool) -> Disposable {
return self.subscribe { event in
MainScheduler.ensureExecutingOnScheduler()
switch event {
case .Next(let boxedValue):
let value = boxedValue
if animated && value != nil {
let transition = CATransition()
transition.duration = 0.25
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
imageView.layer.addAnimation(transition, forKey: kCATransition)
}
})
else {
imageView.layer.removeAllAnimations()
}
imageView.image = value
case .Error(let error):
bindingErrorToInterface(error)
break
case .Completed:
break
}
}
}
}
extension UIImageView {
}

View File

@ -12,14 +12,14 @@ import RxSwift
#endif
import UIKit
extension UILabel {
public func rx_subscribeTextTo(source: Observable<String>) -> Disposable {
return source.subscribe(AnonymousObserver { event in
extension ObservableType where E == String {
public func subscribeTextOf(label: UILabel) -> Disposable {
return self.subscribe { event in
MainScheduler.ensureExecutingOnScheduler()
switch event {
case .Next(let value):
self.text = value
label.text = value
case .Error(let error):
#if DEBUG
rxFatalError("Binding error to textbox: \(error)")
@ -28,6 +28,9 @@ extension UILabel {
case .Completed:
break
}
})
}
}
}
extension UILabel {
}

View File

@ -24,11 +24,11 @@ extension UISearchBar {
return deferred { [weak self] in
let text = self?.text ?? ""
return self?.rx_delegate.observe("searchBar:textDidChange:") ?? empty()
>- map { a in
return (self?.rx_delegate.observe("searchBar:textDidChange:") ?? empty())
.map { a in
return a[1] as? String ?? ""
}
>- startWith(text)
.startWith(text)
}
}
}

View File

@ -12,6 +12,49 @@ import RxSwift
#endif
import UIKit
extension ObservableType {
// data source
// Registers reactive data source with table view.
// Difference between reactive data source and UITableViewDataSource is that reactive
// has additional method:
//
// ```
// func tableView(tableView: UITableView, observedEvent: Event<Element>) -> Void
// ```
//
// If you want to register non reactive data source, please use `rx_setDataSource` method
public func subscribe<DataSource: protocol<RxTableViewDataSourceType, UITableViewDataSource> where E == DataSource.Element>(tableView: UITableView, withReactiveDataSource dataSource: DataSource)
-> Disposable {
return self.subscribeProxyDataSourceForObject(tableView, dataSource: dataSource, retainDataSource: false) { (_: RxTableViewDataSourceProxy, event) -> Void in
dataSource.tableView(tableView, observedEvent: event)
}
}
}
extension ObservableType where E: SequenceType {
// `reloadData` - items subscription methods (it's assumed that there is one section, and it is typed `Void`)
public func subscribeItemsOf(tableView: UITableView, cellFactory: (UITableView, Int, E.Generator.Element) -> UITableViewCell)
-> Disposable {
let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper<E>(cellFactory: cellFactory)
return self.subscribe(tableView, withReactiveDataSource: dataSource)
}
public func subscribeItemsOf<Cell: UITableViewCell>(tableView: UITableView, withCellIdentifier cellIdentifier: String, configureCell: (Int, E.Generator.Element, Cell) -> Void)
-> Disposable {
let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper<E> { (tv, i, item) in
let indexPath = NSIndexPath(forItem: i, inSection: 0)
let cell = tv.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! Cell
configureCell(i, item, cell)
return cell
}
return self.subscribe(tableView, withReactiveDataSource: dataSource)
}
}
extension UITableView {
// factories
@ -33,85 +76,39 @@ extension UITableView {
return installDelegate(proxy, delegate: dataSource, retainDelegate: false, onProxyForObject: self)
}
// data source
// Registers reactive data source with table view.
// Difference between reactive data source and UITableViewDataSource is that reactive
// has additional method:
//
// ```
// func tableView(tableView: UITableView, observedEvent: Event<Element>) -> Void
// ```
//
// If you want to register non reactive data source, please use `rx_setDataSource` method
public func rx_subscribeWithReactiveDataSource<DataSource: protocol<RxTableViewDataSourceType, UITableViewDataSource>>
(dataSource: DataSource)
-> Observable<DataSource.Element> -> Disposable {
return setProxyDataSourceForObject(self, dataSource: dataSource, retainDataSource: false) { (_: RxTableViewDataSourceProxy, event) -> Void in
dataSource.tableView(self, observedEvent: event)
}
}
// `reloadData` - items subscription methods (it's assumed that there is one section, and it is typed `Void`)
public func rx_subscribeItemsTo<Item>
(cellFactory: (UITableView, Int, Item) -> UITableViewCell)
-> Observable<[Item]> -> Disposable {
return { source in
let dataSource = RxTableViewReactiveArrayDataSource<Item>(cellFactory: cellFactory)
return self.rx_subscribeWithReactiveDataSource(dataSource)(source)
}
}
public func rx_subscribeItemsToWithCellIdentifier<Item, Cell: UITableViewCell>
(cellIdentifier: String, configureCell: (NSIndexPath, Item, Cell) -> Void)
-> Observable<[Item]> -> Disposable {
return { source in
let dataSource = RxTableViewReactiveArrayDataSource<Item> { (tv, i, item) in
let indexPath = NSIndexPath(forItem: i, inSection: 0)
let cell = tv.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! Cell
configureCell(indexPath, item, cell)
return cell
}
return self.rx_subscribeWithReactiveDataSource(dataSource)(source)
}
}
// events
public var rx_itemSelected: Observable<NSIndexPath> {
return rx_delegate.observe("tableView:didSelectRowAtIndexPath:")
>- map { a in
.map { a in
return a[1] as! NSIndexPath
}
}
public var rx_itemInserted: Observable<NSIndexPath> {
return rx_dataSource.observe("tableView:commitEditingStyle:forRowAtIndexPath:")
>- filter { a in
.filter { a in
return UITableViewCellEditingStyle(rawValue: (a[1] as! NSNumber).integerValue) == .Insert
}
>- map { a in
.map { a in
return (a[2] as! NSIndexPath)
}
}
public var rx_itemDeleted: Observable<NSIndexPath> {
return rx_dataSource.observe("tableView:commitEditingStyle:forRowAtIndexPath:")
>- filter { a in
.filter { a in
return UITableViewCellEditingStyle(rawValue: (a[1] as! NSNumber).integerValue) == .Delete
}
>- map { a in
.map { a in
return (a[2] as! NSIndexPath)
}
}
public var rx_itemMoved: Observable<ItemMovedEvent> {
return rx_dataSource.observe("tableView:moveRowAtIndexPath:toIndexPath:")
>- map { a in
.map { a in
return ((a[1] as! NSIndexPath), (a[2] as! NSIndexPath))
}
}
@ -119,58 +116,11 @@ extension UITableView {
// typed events
// This method only works in case one of the `rx_subscribeItemsTo` methods was used.
public func rx_modelSelected<T>() -> Observable<T> {
return rx_itemSelected >- map { ip in
return rx_itemSelected .map { ip in
let dataSource: RxTableViewReactiveArrayDataSource<T> = castOrFatalError(self.rx_dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx_subscribeItemsTo` methods was used.")
return dataSource.modelAtIndex(ip.item)!
}
}
}
// deprecated
extension UITableView {
@available(*, deprecated=1.7, message="Replaced by `rx_subscribeWithReactiveDataSource`")
public func rx_subscribeRowsTo<E where E: AnyObject>
(dataSource: UITableViewDataSource)
(source: Observable<[E]>)
-> Disposable {
return rx_setDataSource(dataSource)
}
@available(*, deprecated=1.7, message="Replaced by `rx_setDataSource`")
public func rx_subscribeRowsTo<E where E : AnyObject>
(cellFactory: (UITableView, NSIndexPath, E) -> UITableViewCell)
(source: Observable<[E]>)
-> Disposable {
let l = rx_subscribeItemsTo { (tv: UITableView, i: Int, e: E) -> UITableViewCell in
return cellFactory(tv, NSIndexPath(forItem: i, inSection: 0), e)
}
return l(source)
}
@available(*, deprecated=1.7, message="Replaced by `rx_subscribeItemsToWithCellIdentifier`")
public func rx_subscribeRowsToCellWithIdentifier<E, Cell where E : AnyObject, Cell: UITableViewCell>
(cellIdentifier: String, configureCell: (UITableView, NSIndexPath, E, Cell) -> Void)
(source: Observable<[E]>)
-> Disposable {
let l = rx_subscribeItemsToWithCellIdentifier(cellIdentifier) { (ip: NSIndexPath, e: E, c: Cell) -> Void in
configureCell(self, ip, e, c)
}
return l(source)
}
@available(*, deprecated=1.7, message="Replaced by `rx_itemSelected`")
public func rx_rowTap() -> Observable<(UITableView, Int)> {
return rx_itemSelected
>- map { ip in
return (self, ip.item)
}
}
@available(*, deprecated=1.7, message="Replaced by `rx_modelSelected`")
public func rx_elementTap<E>() -> Observable<E> {
return rx_modelSelected()
}
}
}

View File

@ -21,11 +21,11 @@ extension UITextView {
public var rx_text: Observable<String> {
return deferred { [weak self] in
let text = self?.text ?? ""
return self?.rx_delegate.observe("textViewDidChange:") ?? empty()
>- map { a in
return (self?.rx_delegate.observe("textViewDidChange:") ?? empty())
.map { a in
return (a[0] as? UITextView)?.text ?? ""
}
>- startWith(text)
.startWith(text)
}
}

View File

@ -352,7 +352,7 @@
C8297E7F1B6CF94B000589EA /* PeriodicScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeriodicScheduler.swift; sourceTree = "<group>"; };
C8297E801B6CF94B000589EA /* BehaviorSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BehaviorSubject.swift; sourceTree = "<group>"; };
C8297E811B6CF94B000589EA /* ConnectableObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectableObservableType.swift; sourceTree = "<group>"; };
C8297E821B6CF94B000589EA /* PublishSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = PublishSubject.swift; sourceTree = "<group>"; };
C8297E821B6CF94B000589EA /* PublishSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = PublishSubject.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297E831B6CF94B000589EA /* ReplaySubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplaySubject.swift; sourceTree = "<group>"; };
C8297E841B6CF94B000589EA /* SubjectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubjectType.swift; sourceTree = "<group>"; };
C8297E851B6CF94B000589EA /* Variable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Variable.swift; sourceTree = "<group>"; };
@ -446,8 +446,8 @@
C8297F551B6CF953000589EA /* RxCLLocationManagerDelegateProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = RxCLLocationManagerDelegateProxy.swift; sourceTree = "<group>"; };
C8297F571B6CF953000589EA /* ControlTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ControlTarget.swift; sourceTree = "<group>"; };
C8297F581B6CF953000589EA /* Deallocating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Deallocating.swift; sourceTree = "<group>"; };
C8297F591B6CF953000589EA /* KVOObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = KVOObservable.swift; sourceTree = "<group>"; };
C8297F5A1B6CF953000589EA /* KVOObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = KVOObserver.swift; sourceTree = "<group>"; };
C8297F591B6CF953000589EA /* KVOObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = KVOObservable.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F5A1B6CF953000589EA /* KVOObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = KVOObserver.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F5B1B6CF953000589EA /* DeinitAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeinitAction.swift; sourceTree = "<group>"; };
C8297F5D1B6CF953000589EA /* NSObject+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "NSObject+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F5E1B6CF953000589EA /* NSObject+Rx+CoreGraphics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "NSObject+Rx+CoreGraphics.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
@ -483,23 +483,23 @@
C8297F871B6CF953000589EA /* ItemEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemEvents.swift; sourceTree = "<group>"; };
C8297F891B6CF953000589EA /* CoreDataEntityEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CoreDataEntityEvent.swift; sourceTree = "<group>"; };
C8297F8A1B6CF953000589EA /* NSManagedObjectContext+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "NSManagedObjectContext+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F8B1B6CF953000589EA /* UIBarButtonItem+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIBarButtonItem+Rx.swift"; sourceTree = "<group>"; };
C8297F8B1B6CF953000589EA /* UIBarButtonItem+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIBarButtonItem+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F8C1B6CF953000589EA /* UIButton+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIButton+Rx.swift"; sourceTree = "<group>"; };
C8297F8D1B6CF953000589EA /* UICollectionView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UICollectionView+Rx.swift"; sourceTree = "<group>"; };
C8297F8E1B6CF953000589EA /* UIControl+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIControl+Rx.swift"; sourceTree = "<group>"; };
C8297F8D1B6CF953000589EA /* UICollectionView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UICollectionView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F8E1B6CF953000589EA /* UIControl+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIControl+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F8F1B6CF953000589EA /* UIDatePicker+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIDatePicker+Rx.swift"; sourceTree = "<group>"; };
C8297F901B6CF953000589EA /* UIImageView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIImageView+Rx.swift"; sourceTree = "<group>"; };
C8297F911B6CF953000589EA /* UILabel+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UILabel+Rx.swift"; sourceTree = "<group>"; };
C8297F911B6CF953000589EA /* UILabel+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UILabel+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F921B6CF953000589EA /* UIScrollView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIScrollView+Rx.swift"; sourceTree = "<group>"; };
C8297F931B6CF953000589EA /* UISearchBar+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UISearchBar+Rx.swift"; sourceTree = "<group>"; };
C8297F931B6CF953000589EA /* UISearchBar+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UISearchBar+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F941B6CF953000589EA /* UISlider+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UISlider+Rx.swift"; sourceTree = "<group>"; };
C8297F951B6CF953000589EA /* UITableView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UITableView+Rx.swift"; sourceTree = "<group>"; };
C8297F961B6CF953000589EA /* UITextField+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UITextField+Rx.swift"; sourceTree = "<group>"; };
C8297F971B6CF953000589EA /* UITextView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UITextView+Rx.swift"; sourceTree = "<group>"; };
C8297F981B6CF953000589EA /* UIGestureRecognizer+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIGestureRecognizer+Rx.swift"; sourceTree = "<group>"; };
C8297F991B6CF953000589EA /* UIActionSheet+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIActionSheet+Rx.swift"; sourceTree = "<group>"; };
C8297F9A1B6CF953000589EA /* UIAlertView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIAlertView+Rx.swift"; sourceTree = "<group>"; };
C8297F9B1B6CF953000589EA /* UISegmentedControl+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UISegmentedControl+Rx.swift"; sourceTree = "<group>"; };
C8297F951B6CF953000589EA /* UITableView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UITableView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F961B6CF953000589EA /* UITextField+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UITextField+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F971B6CF953000589EA /* UITextView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UITextView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F981B6CF953000589EA /* UIGestureRecognizer+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIGestureRecognizer+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F991B6CF953000589EA /* UIActionSheet+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIActionSheet+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F9A1B6CF953000589EA /* UIAlertView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UIAlertView+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F9B1B6CF953000589EA /* UISegmentedControl+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UISegmentedControl+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8297F9C1B6CF953000589EA /* UISwitch+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "UISwitch+Rx.swift"; sourceTree = "<group>"; };
C8297F9E1B6CF953000589EA /* RxCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RxCocoa.h; sourceTree = "<group>"; };
C8297F9F1B6CF953000589EA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -1750,6 +1750,7 @@
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "RxExample/Info-OSX.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
OTHER_LDFLAGS = "-objc_loadall";
SDKROOT = macosx;
};
@ -1761,6 +1762,7 @@
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "RxExample/Info-OSX.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
OTHER_LDFLAGS = "-objc_loadall";
SDKROOT = macosx;
};
@ -1826,6 +1828,7 @@
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "RxExample/Info-OSX.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
OTHER_LDFLAGS = "-objc_loadall";
SDKROOT = macosx;
};

View File

@ -62,57 +62,57 @@ class APIWrappersViewController: ViewController {
let av = UIAlertView(title: "Title", message: "The message", delegate: nil, cancelButtonTitle: "Cancel", otherButtonTitles: "OK", "Two", "Three", "Four", "Five")
openActionSheet.rx_tap
>- subscribeNext { x in
.subscribeNext { x in
ash.showInView(self.view)
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
openAlertView.rx_tap
>- subscribeNext { x in
.subscribeNext { x in
av.show()
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UIActionSheet
ash.rx_clickedButtonAtIndex
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIActionSheet clickedButtonAtIndex \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
ash.rx_willDismissWithButtonIndex
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIActionSheet willDismissWithButtonIndex \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
ash.rx_didDismissWithButtonIndex
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIActionSheet didDismissWithButtonIndex \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UIAlertView
av.rx_clickedButtonAtIndex
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIAlertView clickedButtonAtIndex \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
av.rx_willDismissWithButtonIndex
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIAlertView willDismissWithButtonIndex \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
av.rx_didDismissWithButtonIndex
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIAlertView didDismissWithButtonIndex \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
@ -123,73 +123,73 @@ class APIWrappersViewController: ViewController {
// MARK: UIBarButtonItem
bbitem.rx_tap
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIBarButtonItem Tapped")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UISegmentedControl
segmentedControl.rx_value
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UISegmentedControl value \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UISwitch
switcher.rx_value
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UISwitch value \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UIButton
button.rx_tap
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIButton Tapped")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UISlider
slider.rx_value
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UISlider value \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UIDatePicker
datePicker.rx_date
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIDatePicker date \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UITextField
textField.rx_text
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UITextField text \(x)")
self?.textField.resignFirstResponder()
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: UIGestureRecognizer
mypan.rx_event
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("UIGestureRecognizer event \(x.state)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// MARK: CLLocationManager
@ -201,16 +201,16 @@ class APIWrappersViewController: ViewController {
}
manager.rx_didUpdateLocations
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("rx_didUpdateLocations \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
manager.rx_didFailWithError
>- subscribeNext { [weak self] x in
.subscribeNext { [weak self] x in
self?.debug("rx_didFailWithError \(x)")
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
manager.startUpdatingLocation()

View File

@ -46,7 +46,7 @@ class GitHubAPI {
let URL = NSURL(string: "https://github.com/\(URLEscape(username))")!
let request = NSURLRequest(URL: URL)
return self.URLSession.rx_response(request)
>- map { (maybeData, maybeResponse) in
.map { (maybeData, maybeResponse) in
if let response = maybeResponse as? NSHTTPURLResponse {
return response.statusCode == 404
}
@ -54,17 +54,15 @@ class GitHubAPI {
return false
}
}
>- observeSingleOn(self.dataScheduler)
>- onError { result in
return just(false)
}
.observeSingleOn(self.dataScheduler)
.catchError(false)
}
func signup(username: String, password: String) -> Observable<SignupState> {
// this is also just a mock
let signupResult = SignupState.SignedUp(signedUp: arc4random() % 5 == 0 ? false : true)
return concat([just(signupResult), never()])
>- throttle(5, MainScheduler.sharedInstance)
>- startWith(SignupState.SigningUp)
.throttle(5, MainScheduler.sharedInstance)
.startWith(SignupState.SigningUp)
}
}

View File

@ -43,7 +43,7 @@ class ValidationService {
let loadingValue = (valid: nil as Bool?, message: "Checking availabilty ..." as String?)
return API.usernameAvailable(username)
>- map { available in
.map { available in
if available {
return (true, "Username available")
}
@ -51,7 +51,7 @@ class ValidationService {
return (false, "Username already taken")
}
}
>- startWith(loadingValue)
.startWith(loadingValue)
}
func validatePassword(password: String) -> ValidationResult {
@ -103,19 +103,21 @@ class GitHubSignupViewController : ViewController {
func bindValidationResultToUI(source: Observable<(valid: Bool?, message: String?)>,
validationErrorLabel: UILabel) {
source >- subscribeNext { [unowned self] v in
let validationColor: UIColor
if let valid = v.valid {
validationColor = valid ? okColor : errorColor
source
.subscribeNext { [unowned self] v in
let validationColor: UIColor
if let valid = v.valid {
validationColor = valid ? okColor : errorColor
}
else {
validationColor = UIColor.grayColor()
}
validationErrorLabel.textColor = validationColor
validationErrorLabel.text = v.message ?? ""
}
else {
validationColor = UIColor.grayColor()
}
validationErrorLabel.textColor = validationColor
validationErrorLabel.text = v.message ?? ""
} >- disposeBag.addDisposable
.addDisposableTo(disposeBag)
}
func dismissKeyboard(gr: UITapGestureRecognizer) {
@ -141,31 +143,31 @@ class GitHubSignupViewController : ViewController {
let signupSampler = self.signupOutlet.rx_tap
let usernameValidation = username
>- map { username in
.map { username in
return validationService.validateUsername(username)
}
>- switchLatest
>- variable
.switchLatest
.variable
let passwordValidation = password
>- map { password in
.map { password in
return validationService.validatePassword(password)
}
>- variable
.variable
let repeatPasswordValidation = combineLatest(password, repeatPassword) { (password, repeatedPassword) in
validationService.validateRepeatedPassword(password, repeatedPassword: repeatedPassword)
}
>- variable
.variable
let signingProcess = combineLatest(username, password) { ($0, $1) }
>- sampleLatest(signupSampler)
>- map { (username, password) in
.sampleLatest(signupSampler)
.map { (username, password) in
return API.signup(username, password: password)
}
>- switchLatest
>- startWith(.InitialState)
>- variable
.switchLatest
.startWith(.InitialState)
.variable
let signupEnabled = combineLatest(
usernameValidation,
@ -192,15 +194,15 @@ class GitHubSignupViewController : ViewController {
)
signupEnabled
>- subscribeNext { [unowned self] valid in
.subscribeNext { [unowned self] valid in
self.signupOutlet.enabled = valid
self.signupOutlet.alpha = valid ? 1.0 : 0.5
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
signingProcess
>- subscribeNext { [unowned self] signingResult in
.subscribeNext { [unowned self] signingResult in
switch signingResult {
case .SigningUp:
self.signingUpOulet.hidden = false
@ -221,7 +223,7 @@ class GitHubSignupViewController : ViewController {
self.signingUpOulet.hidden = true
}
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
}
// This is one of the reasons why it's a good idea for disposal to be detached from allocations.

View File

@ -33,49 +33,49 @@ class IntroductionExampleViewController : ViewController {
// bind result to UI
sum
>- map { (a, b) in
.map { (a, b) in
return "\(a + b)"
}
>- c.rx_subscribeTextTo
>- disposeBag.addDisposable
.subscribeTextOf(c)
.addDisposableTo(disposeBag)
// Also, tell it out loud
let speech = NSSpeechSynthesizer()
sum
>- map { (a, b) in
.map { (a, b) in
return "\(a) + \(b) = \(a + b)"
}
>- subscribeNext { result in
.subscribeNext { result in
if speech.speaking {
speech.stopSpeaking()
}
speech.startSpeakingString(result)
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
slider.rx_value
>- subscribeNext { value in
.subscribeNext { value in
self.sliderValue.stringValue = "\(Int(value))"
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
sliderValue.rx_text
>- subscribeNext { value in
.subscribeNext { value in
let doubleValue = value.toDouble() ?? 0.0
self.slider.doubleValue = doubleValue
self.sliderValue.stringValue = "\(Int(doubleValue))"
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
disposeButton.rx_tap
>- subscribeNext { [unowned self] _ in
.subscribeNext { [unowned self] _ in
print("Unbound everything")
self.disposeBag = DisposeBag()
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
}
}

View File

@ -109,14 +109,14 @@ class PartialUpdatesViewController : ViewController {
timer = NSTimer.scheduledTimerWithTimeInterval(0.6, target: self, selector: "randomize", userInfo: nil, repeats: true)
#endif
self.sections.next(generator.sections)
self.sections.sendNext(generator.sections)
let tvAnimatedDataSource = RxTableViewSectionedAnimatedDataSource<NumberSection>()
let reloadDataSource = RxTableViewSectionedReloadDataSource<NumberSection>()
skinTableViewDataSource(tvAnimatedDataSource)
skinTableViewDataSource(reloadDataSource)
let newSections = self.sections >- skip(1)
let newSections = self.sections .skip(1)
let initialState = [Changeset.initialValue(self.sections.value)]
@ -125,15 +125,15 @@ class PartialUpdatesViewController : ViewController {
let updates = zip(self.sections, newSections) { (old, new) in
return differentiate(old, finalSections: new)
}
>- startWith(initialState)
.startWith(initialState)
updates
>- partialUpdatesTableViewOutlet.rx_subscribeWithReactiveDataSource(tvAnimatedDataSource)
>- disposeBag.addDisposable
.partialUpdatesTableViewOutlet.rx_subscribeWithReactiveDataSource(tvAnimatedDataSource)
.disposeBag.addDisposable
self.sections
>- reloadTableViewOutlet.rx_subscribeWithReactiveDataSource(reloadDataSource)
>- disposeBag.addDisposable
.reloadTableViewOutlet.rx_subscribeWithReactiveDataSource(reloadDataSource)
.disposeBag.addDisposable
// Collection view logic works, but when clicking fast because of internal bugs
// collection view will sometimes get confused. I know what you are thinking,
@ -152,29 +152,29 @@ class PartialUpdatesViewController : ViewController {
skinCollectionViewDataSource(cvAnimatedDataSource)
updates
>- partialUpdatesCollectionViewOutlet.rx_subscribeWithReactiveDataSource(cvAnimatedDataSource)
>- disposeBag.addDisposable
.partialUpdatesCollectionViewOutlet.rx_subscribeWithReactiveDataSource(cvAnimatedDataSource)
.disposeBag.addDisposable
#else
let cvReloadDataSource = RxCollectionViewSectionedReloadDataSource<NumberSection>()
skinCollectionViewDataSource(cvReloadDataSource)
self.sections
>- partialUpdatesCollectionViewOutlet.rx_subscribeWithReactiveDataSource(cvReloadDataSource)
>- disposeBag.addDisposable
.partialUpdatesCollectionViewOutlet.rx_subscribeWithReactiveDataSource(cvReloadDataSource)
.disposeBag.addDisposable
#endif
// touches
partialUpdatesCollectionViewOutlet.rx_itemSelected
>- subscribeNext { [unowned self] i in
.subscribeNext { [unowned self] i in
print("Let me guess, it's .... It's \(self.generator.sections[i.section].items[i.item]), isn't it? Yeah, I've got it.")
}
>- disposeBag.addDisposable
.disposeBag.addDisposable
merge(from([partialUpdatesTableViewOutlet.rx_itemSelected, reloadTableViewOutlet.rx_itemSelected]))
>- subscribeNext { [unowned self] i in
.subscribeNext { [unowned self] i in
print("I have a feeling it's .... \(self.generator.sections[i.section].items[i.item])?")
}
>- disposeBag.addDisposable
.disposeBag.addDisposable
}
override func viewWillDisappear(animated: Bool) {
@ -192,6 +192,6 @@ class PartialUpdatesViewController : ViewController {
//print(values)
sections.next(values)
sections.sendNext(values)
}*/
}

View File

@ -32,12 +32,12 @@ class DetailViewController: ViewController {
let request = NSURLRequest(URL: url)
NSURLSession.sharedSession().rx_data(request)
>- map { data in
.map { data in
UIImage(data: data)
}
>- observeSingleOn($.mainScheduler)
>- imageView.rx_subscribeImageTo
>- disposeBag.addDisposable
.observeSingleOn($.mainScheduler)
.subscribeImageOf(imageView)
.addDisposableTo(disposeBag)
label.text = user.firstName + " " + user.lastName
}

View File

@ -20,13 +20,13 @@ class RandomUserAPI {
func getExampleUserResultSet() -> Observable<[User]> {
let url = NSURL(string: "http://api.randomuser.me/?results=20")!
return NSURLSession.sharedSession().rx_JSON(url)
>- observeSingleOn(Dependencies.sharedDependencies.backgroundWorkScheduler)
>- mapOrDie { json in
.observeSingleOn(Dependencies.sharedDependencies.backgroundWorkScheduler)
.mapOrDie { json in
return castOrFail(json).flatMap { (json: [String: AnyObject]) in
return self.parseJSON(json)
}
}
>- observeSingleOn(Dependencies.sharedDependencies.mainScheduler)
.observeSingleOn(Dependencies.sharedDependencies.mainScheduler)
}
private func parseJSON(json: [String: AnyObject]) -> RxResult<[User]> {

View File

@ -43,10 +43,10 @@ class TableViewController: ViewController, UITableViewDelegate {
// This is for demonstration purposes of UITableViewDelegate/DataSource
// only, try to not do something like this in your app
allUsers
>- subscribeNext { [unowned self] n in
.subscribeNext { [unowned self] n in
self.allSections = n
}
>- disposeBag.addDisposable
.disposeBag.addDisposable
dataSource.cellFactory = { (tv, ip, user: User) in
let cell = tv.dequeueReusableCellWithIdentifier("Cell")!
@ -60,45 +60,45 @@ class TableViewController: ViewController, UITableViewDelegate {
// reactive data source
allUsers
>- tableView.rx_subscribeWithReactiveDataSource(dataSource)
>- disposeBag.addDisposable
.tableView.rx_subscribeWithReactiveDataSource(dataSource)
.disposeBag.addDisposable
// customization using delegate
// RxTableViewDelegateBridge will forward correct messages
tableView.rx_setDelegate(self)
>- disposeBag.addDisposable
.disposeBag.addDisposable
tableView.rx_itemSelected
>- subscribeNext { [unowned self] indexPath in
.subscribeNext { [unowned self] indexPath in
self.showDetailsForUserAtIndexPath(indexPath)
}
>- disposeBag.addDisposable
.disposeBag.addDisposable
tableView.rx_itemDeleted
>- subscribeNext { [unowned self] indexPath in
.subscribeNext { [unowned self] indexPath in
self.removeUser(indexPath)
}
>- disposeBag.addDisposable
.disposeBag.addDisposable
tableView.rx_itemMoved
>- subscribeNext { [unowned self] (s, d) in
.subscribeNext { [unowned self] (s, d) in
self.moveUserFrom(s, to: d)
}
>- disposeBag.addDisposable
.disposeBag.addDisposable
// Rx content offset
tableView.rx_contentOffset
>- subscribeNext { co in
.subscribeNext { co in
print("Content offset from Rx observer \(co)")
}
RandomUserAPI.sharedAPI.getExampleUserResultSet()
>- subscribeNext { [unowned self] array in
self.users.next(array)
.subscribeNext { [unowned self] array in
self.users.sendNext(array)
}
>- disposeBag.addDisposable
.disposeBag.addDisposable
favoriteUsers.next([User(firstName: "Super", lastName: "Man", imageURL: "http://nerdreactor.com/wp-content/uploads/2015/02/Superman1.jpg")])
favoriteUsers.sendNext([User(firstName: "Super", lastName: "Man", imageURL: "http://nerdreactor.com/wp-content/uploads/2015/02/Superman1.jpg")])
}
override func setEditing(editing: Bool, animated: Bool) {
@ -162,11 +162,11 @@ class TableViewController: ViewController, UITableViewDelegate {
case 0:
fromArray = favoriteUsers.value
user = fromArray.removeAtIndex(from.row)
favoriteUsers.next(fromArray)
favoriteUsers.sendNext(fromArray)
case 1:
fromArray = users.value
user = fromArray.removeAtIndex(from.row)
users.next(fromArray)
users.sendNext(fromArray)
default:
fatalError("Section out of range")
}
@ -176,11 +176,11 @@ class TableViewController: ViewController, UITableViewDelegate {
case 0:
toArray = favoriteUsers.value
toArray.insert(user, atIndex: to.row)
favoriteUsers.next(toArray)
favoriteUsers.sendNext(toArray)
case 1:
toArray = users.value
toArray.insert(user, atIndex: to.row)
users.next(toArray)
users.sendNext(toArray)
default:
fatalError("Section out of range")
}
@ -189,7 +189,7 @@ class TableViewController: ViewController, UITableViewDelegate {
func addUser(user: User) {
var array = users.value
array.append(user)
users.next(array)
users.sendNext(array)
}
func removeUser(indexPath: NSIndexPath) {
@ -198,11 +198,11 @@ class TableViewController: ViewController, UITableViewDelegate {
case 0:
array = favoriteUsers.value
array.removeAtIndex(indexPath.row)
favoriteUsers.next(array)
favoriteUsers.sendNext(array)
case 1:
array = users.value
array.removeAtIndex(indexPath.row)
users.next(array)
users.sendNext(array)
default:
fatalError("Section out of range")
}

View File

@ -29,8 +29,8 @@ class SearchResultViewModel {
let URLs = configureImageURLs()
self.imageURLs = URLs >- onError ([])
self.title = configureTitle(URLs) >- onError("Error during fetching")
self.imageURLs = URLs.catchError ([])
self.title = configureTitle(URLs).catchError("Error during fetching")
}
// private methods
@ -41,9 +41,9 @@ class SearchResultViewModel {
let loadingValue: [NSURL]? = nil
return imageURLs
>- map { makeOptional($0) }
>- startWith(loadingValue)
>- map { URLs in
.map { makeOptional($0) }
.startWith(loadingValue)
.map { URLs in
if let URLs = URLs {
return "\(searchResult.title) (\(URLs.count)) pictures)"
}
@ -56,15 +56,15 @@ class SearchResultViewModel {
func configureImageURLs() -> Observable<[NSURL]> {
let searchResult = self.searchResult
return API.articleContent(searchResult)
>- observeSingleOn($.backgroundWorkScheduler)
>- map { page in
.observeSingleOn($.backgroundWorkScheduler)
.map { page in
do {
return try parseImageURLsfromHTMLSuitableForDisplay(page.text)
} catch {
return []
}
}
>- observeSingleOn($.mainScheduler)
>- variable
.observeSingleOn($.mainScheduler)
.variable
}
}

View File

@ -12,12 +12,12 @@ import RxSwift
import RxCocoa
#endif
class SearchViewModel: Disposable {
class SearchViewModel {
// outputs
let rows: Observable<[SearchResultViewModel]>
let subscriptions = CompositeDisposable()
let subscriptions = DisposeBag()
// public methods
@ -29,31 +29,28 @@ class SearchViewModel: Disposable {
let API = DefaultWikipediaAPI.sharedAPI
self.rows = searchText
>- throttle(0.3, $.mainScheduler)
>- distinctUntilChanged
>- map { query in
.throttle(0.3, $.mainScheduler)
.distinctUntilChanged()
.map { query in
API.getSearchResults(query)
>- retry(3)
>- startWith([]) // clears results on new search term
>- onError ([])
.retry(3)
.startWith([]) // clears results on new search term
.catchError([])
}
>- switchLatest
>- map { results in
.switchLatest
.map { results in
results.map {
SearchResultViewModel(
searchResult: $0
)
}
}
}
selectedResult
>- subscribeNext { searchResult in
.subscribeNext { searchResult in
wireframe.openURL(searchResult.searchResult.URL)
}
>- subscriptions.addDisposable
.addDisposableTo(subscriptions)
}
func dispose() {
subscriptions.dispose()
}
}

View File

@ -22,7 +22,9 @@ public class CollectionViewImageCell: UICollectionViewCell {
didSet {
let disposeBag = DisposeBag()
self.image >- imageOutlet.rx_subscribeImageTo(true) >- disposeBag.addDisposable
self.image
.subscribeImageOf(imageOutlet, animated: true)
.addDisposableTo(disposeBag)
self.disposeBag = disposeBag
}

View File

@ -35,19 +35,22 @@ public class WikipediaSearchCell: UITableViewCell {
let disposeBag = DisposeBag()
self.titleOutlet.rx_subscribeTextTo(viewModel?.title ?? just("")) >- disposeBag.addDisposable
(viewModel?.title ?? just(""))
.subscribeTextOf(self.titleOutlet)
.addDisposableTo(disposeBag)
self.URLOutlet.text = viewModel.searchResult.URL.absoluteString ?? ""
viewModel.imageURLs
>- self.imagesOutlet.rx_subscribeItemsToWithCellIdentifier("ImageCell") { [unowned self] (_, URL, cell: CollectionViewImageCell) in
.subscribeItemsOf(self.imagesOutlet, withCellIdentifier: "ImageCell") { [unowned self] (_, URL, cell: CollectionViewImageCell) in
let loadingPlaceholder: UIImage? = nil
cell.image = self.imageService.imageFromURL(URL)
>- map { $0 as UIImage? }
>- onError(nil)
>- startWith(loadingPlaceholder)
.map { $0 as UIImage? }
.catchError(nil)
.startWith(loadingPlaceholder)
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
self.disposeBag = disposeBag
}

View File

@ -43,24 +43,22 @@ class WikipediaSearchViewController: ViewController {
// map table view rows
// {
viewModel.rows
>- resultsTableView.rx_subscribeItemsToWithCellIdentifier("WikipediaSearchCell") { (_, viewModel, cell: WikipediaSearchCell) in
.subscribeItemsOf(resultsTableView, withCellIdentifier: "WikipediaSearchCell") { (_, viewModel, cell: WikipediaSearchCell) in
cell.viewModel = viewModel
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
// }
// dismiss keyboard on scroll
// {
resultsTableView.rx_contentOffset
>- subscribeNext { _ in
.subscribeNext { _ in
if searchBar.isFirstResponder() {
_ = searchBar.resignFirstResponder()
}
}
>- disposeBag.addDisposable
.addDisposableTo(disposeBag)
disposeBag.addDisposable(viewModel)
self.viewModel = viewModel
// }
}

View File

@ -42,13 +42,13 @@ class DefaultWikipediaAPI: WikipediaAPI {
let url = NSURL(string: urlContent)!
return $.URLSession.rx_JSON(url)
>- observeSingleOn($.backgroundWorkScheduler)
>- mapOrDie { json in
.observeSingleOn($.backgroundWorkScheduler)
.mapOrDie { json in
return castOrFail(json).flatMap { (json: [AnyObject]) in
return WikipediaSearchResult.parseJSON(json)
}
}
>- observeSingleOn($.mainScheduler)
.observeSingleOn($.mainScheduler)
}
// http://en.wikipedia.org/w/api.php?action=parse&page=rx&format=json
@ -61,11 +61,11 @@ class DefaultWikipediaAPI: WikipediaAPI {
}
return $.URLSession.rx_JSON(url!)
>- mapOrDie { jsonResult in
.mapOrDie { jsonResult in
return castOrFail(jsonResult).flatMap { (json: NSDictionary) in
return WikipediaPage.parseJSON(json)
}
}
>- observeSingleOn($.mainScheduler)
.observeSingleOn($.mainScheduler)
}
}

View File

@ -41,19 +41,22 @@ class DefaultImageService: ImageService {
self.imageCache.countLimit = 20
}
func decodeImage(imageData: Observable<NSData>) -> Observable<Image> {
return imageData >- observeSingleOn($.backgroundWorkScheduler) >- mapOrDie { data in
let maybeImage = Image(data: data)
if maybeImage == nil {
// some error
return failure(apiError("Decoding image error"))
func decodeImage(imageData: NSData) -> Observable<Image> {
return just(imageData)
.observeSingleOn($.backgroundWorkScheduler)
.mapOrDie { data in
let maybeImage = Image(data: data)
if maybeImage == nil {
// some error
return failure(apiError("Decoding image error"))
}
let image = maybeImage!
return success(image)
}
let image = maybeImage!
return success(image)
} >- observeSingleOn($.mainScheduler)
.observeSingleOn($.mainScheduler)
}
func imageFromURL(URL: NSURL) -> Observable<Image> {
@ -71,17 +74,19 @@ class DefaultImageService: ImageService {
// does image data cache contain anything
if let cachedData = cachedData {
decodedImage = just(cachedData) >- self.decodeImage
decodedImage = self.decodeImage(cachedData)
}
else {
// fetch from network
decodedImage = self.$.URLSession.rx_data(NSURLRequest(URL: URL)) >- doOnNext { data in
self.imageDataCache.setObject(data, forKey: URL)
} >- self.decodeImage
decodedImage = self.$.URLSession.rx_data(NSURLRequest(URL: URL))
.doOnNext { data in
self.imageDataCache.setObject(data, forKey: URL)
}
.flatMap(self.decodeImage)
}
}
return decodedImage >- doOnNext { image in
return decodedImage .doOnNext { image in
self.imageCache.setObject(image, forKey: URL)
}
}

View File

@ -108,8 +108,6 @@
C88BB86A1B07E5ED0064D411 /* Rx.h in Headers */ = {isa = PBXBuildFile; fileRef = C8A56B3F1AD7435900B4673B /* Rx.h */; };
C88BB86B1B07E5ED0064D411 /* RxSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = C8A56ADC1AD7424700B4673B /* RxSwift.h */; settings = {ATTRIBUTES = (Public, ); }; };
C88BB86C1B07E5ED0064D411 /* Rx.pch in Headers */ = {isa = PBXBuildFile; fileRef = C8A56B401AD7435900B4673B /* Rx.pch */; };
C897EC2D1B10D3F4009C2CB0 /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC2B1B10D3F4009C2CB0 /* ConnectableObservableType.swift */; };
C897EC2E1B10D3F4009C2CB0 /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC2B1B10D3F4009C2CB0 /* ConnectableObservableType.swift */; };
C897EC2F1B10D3F4009C2CB0 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC2C1B10D3F4009C2CB0 /* SubjectType.swift */; };
C897EC301B10D3F4009C2CB0 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC2C1B10D3F4009C2CB0 /* SubjectType.swift */; };
C897EC321B10D426009C2CB0 /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC311B10D426009C2CB0 /* BehaviorSubject.swift */; };
@ -212,6 +210,10 @@
C8CC5E781B24D7440074DCE0 /* TakeUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CC5E771B24D7440074DCE0 /* TakeUntil.swift */; };
C8CC5E791B24D7440074DCE0 /* TakeUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CC5E771B24D7440074DCE0 /* TakeUntil.swift */; };
C8D5592B1AE32FBB00DE7BDB /* Defer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D5592A1AE32FBB00DE7BDB /* Defer.swift */; };
C8D6756A1B76AD46005264ED /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D675691B76AD46005264ED /* ObservableType.swift */; };
C8D6756B1B76AD46005264ED /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D675691B76AD46005264ED /* ObservableType.swift */; };
C8D675701B76BC26005264ED /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D6756F1B76BC26005264ED /* ConnectableObservableType.swift */; };
C8D675711B76BC26005264ED /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D6756F1B76BC26005264ED /* ConnectableObservableType.swift */; };
C8DA57E91AEB9F7D0035AF28 /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DA57E81AEB9F7D0035AF28 /* CombineLatest.swift */; };
C8FBCF9A1B0FB3DA0091DBFA /* RxBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FBCF991B0FB3DA0091DBFA /* RxBox.swift */; };
C8FBCF9B1B0FB3DA0091DBFA /* RxBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FBCF991B0FB3DA0091DBFA /* RxBox.swift */; };
@ -252,7 +254,6 @@
C87CF6101B1B916500283912 /* Scheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scheduler.swift; sourceTree = "<group>"; };
C88192851AFEA61A00F0F1ED /* StartWith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartWith.swift; sourceTree = "<group>"; };
C88BB8711B07E5ED0064D411 /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C897EC2B1B10D3F4009C2CB0 /* ConnectableObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectableObservableType.swift; sourceTree = "<group>"; };
C897EC2C1B10D3F4009C2CB0 /* SubjectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubjectType.swift; sourceTree = "<group>"; };
C897EC311B10D426009C2CB0 /* BehaviorSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BehaviorSubject.swift; sourceTree = "<group>"; };
C897EC341B10D8F2009C2CB0 /* PublishSubject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = PublishSubject.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
@ -338,6 +339,8 @@
C8CC5E741B24AE600074DCE0 /* SafeObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SafeObserver.swift; sourceTree = "<group>"; };
C8CC5E771B24D7440074DCE0 /* TakeUntil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TakeUntil.swift; sourceTree = "<group>"; };
C8D5592A1AE32FBB00DE7BDB /* Defer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Defer.swift; sourceTree = "<group>"; };
C8D675691B76AD46005264ED /* ObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservableType.swift; sourceTree = "<group>"; };
C8D6756F1B76BC26005264ED /* ConnectableObservableType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectableObservableType.swift; sourceTree = "<group>"; };
C8DA57E81AEB9F7D0035AF28 /* CombineLatest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombineLatest.swift; sourceTree = "<group>"; };
C8FBCF991B0FB3DA0091DBFA /* RxBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxBox.swift; sourceTree = "<group>"; };
C8FBCF9C1B0FE2B00091DBFA /* Observer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Observer.swift; sourceTree = "<group>"; };
@ -386,7 +389,6 @@
isa = PBXGroup;
children = (
C897EC311B10D426009C2CB0 /* BehaviorSubject.swift */,
C897EC2B1B10D3F4009C2CB0 /* ConnectableObservableType.swift */,
C897EC341B10D8F2009C2CB0 /* PublishSubject.swift */,
C8AED7B11B3C66B000678DDE /* ReplaySubject.swift */,
C897EC2C1B10D3F4009C2CB0 /* SubjectType.swift */,
@ -420,28 +422,30 @@
C8A56B401AD7435900B4673B /* Rx.pch */,
C8A56AFC1AD7435800B4673B /* AnyObject+Rx.swift */,
C8A56AFD1AD7435800B4673B /* Cancelable.swift */,
C8D6756F1B76BC26005264ED /* ConnectableObservableType.swift */,
C8A56B041AD7435800B4673B /* Disposable.swift */,
C8A56B0D1AD7435800B4673B /* Error.swift */,
C8A56B0E1AD7435800B4673B /* Event.swift */,
C87CF60F1B1B916500283912 /* ImmediateScheduler.swift */,
C8A56B0F1AD7435800B4673B /* Observable.swift */,
C8A56B101AD7435800B4673B /* Observable+Extensions.swift */,
C8D675691B76AD46005264ED /* ObservableType.swift */,
C8FBCF9C1B0FE2B00091DBFA /* Observer.swift */,
C8A56B331AD7435800B4673B /* ObserverOf.swift */,
C8A56B3D1AD7435900B4673B /* ObserverType.swift */,
C80B560D1B2CD4FC008F915D /* ObserverType+Extensions.swift */,
C8A56B101AD7435800B4673B /* Observable+Extensions.swift */,
C8A56B331AD7435800B4673B /* ObserverOf.swift */,
C8A56B3E1AD7435900B4673B /* RxResult.swift */,
C8FBCF991B0FB3DA0091DBFA /* RxBox.swift */,
C8A56B411AD7435900B4673B /* Rx.swift */,
C87CF60F1B1B916500283912 /* ImmediateScheduler.swift */,
C87CF6101B1B916500283912 /* Scheduler.swift */,
C8B35B821B234BF7009851DA /* PeriodicScheduler.swift */,
C897EC2A1B10D3F4009C2CB0 /* Subjects */,
C8A56B411AD7435900B4673B /* Rx.swift */,
C8FBCF991B0FB3DA0091DBFA /* RxBox.swift */,
C8A56B3E1AD7435900B4673B /* RxResult.swift */,
C87CF6101B1B916500283912 /* Scheduler.swift */,
C8A56AFE1AD7435800B4673B /* Concurrency */,
C8A56B011AD7435800B4673B /* DataStructures */,
C8A56B051AD7435800B4673B /* Disposables */,
C8A56B111AD7435800B4673B /* Observables */,
C8A56B341AD7435800B4673B /* Observers */,
C87CF5F31B1B7EC300283912 /* Schedulers */,
C897EC2A1B10D3F4009C2CB0 /* Subjects */,
C8A56ADA1AD7424700B4673B /* Supporting Files */,
);
path = RxSwift;
@ -725,6 +729,7 @@
C87CF6061B1B7EC300283912 /* MainScheduler.swift in Sources */,
C88BB82B1B07E5ED0064D411 /* Bag.swift in Sources */,
C805FC441B6437F80072FB83 /* BooleanDisposable.swift in Sources */,
C8D6756B1B76AD46005264ED /* ObservableType.swift in Sources */,
C8FDC5FF1B2B88670065F8D9 /* NAryDisposable.swift in Sources */,
C88BB82C1B07E5ED0064D411 /* DisposeBase.swift in Sources */,
C8FDC5F61B2B3D280065F8D9 /* BinaryDisposable.swift in Sources */,
@ -743,7 +748,6 @@
C83CEA331B2495D7006828AC /* TakeWhile.swift in Sources */,
C897EC331B10D426009C2CB0 /* BehaviorSubject.swift in Sources */,
C8FDC5FC1B2B884F0065F8D9 /* StableCompositeDisposable.swift in Sources */,
C897EC2E1B10D3F4009C2CB0 /* ConnectableObservableType.swift in Sources */,
C88BB8391B07E5ED0064D411 /* Aggregate.swift in Sources */,
C88BB83A1B07E5ED0064D411 /* AnonymousDisposable.swift in Sources */,
C88BB83B1B07E5ED0064D411 /* Merge.swift in Sources */,
@ -788,6 +792,7 @@
C88BB8581B07E5ED0064D411 /* Lock.swift in Sources */,
C88BB8591B07E5ED0064D411 /* Observable.swift in Sources */,
C88BB85A1B07E5ED0064D411 /* Disposable.swift in Sources */,
C8D675711B76BC26005264ED /* ConnectableObservableType.swift in Sources */,
C88BB85B1B07E5ED0064D411 /* AsObservable.swift in Sources */,
C88BB85C1B07E5ED0064D411 /* Do.swift in Sources */,
C88BB85D1B07E5ED0064D411 /* SingleAssignmentDisposable.swift in Sources */,
@ -839,6 +844,7 @@
C87CF6051B1B7EC300283912 /* MainScheduler.swift in Sources */,
C8A56B501AD7435900B4673B /* Bag.swift in Sources */,
C805FC431B6437F80072FB83 /* BooleanDisposable.swift in Sources */,
C8D6756A1B76AD46005264ED /* ObservableType.swift in Sources */,
C8FDC5FE1B2B88670065F8D9 /* NAryDisposable.swift in Sources */,
C8A56B571AD7435900B4673B /* DisposeBase.swift in Sources */,
C8FDC5F51B2B3D280065F8D9 /* BinaryDisposable.swift in Sources */,
@ -857,7 +863,6 @@
C83CEA321B2495D7006828AC /* TakeWhile.swift in Sources */,
C897EC321B10D426009C2CB0 /* BehaviorSubject.swift in Sources */,
C8FDC5FB1B2B884F0065F8D9 /* StableCompositeDisposable.swift in Sources */,
C897EC2D1B10D3F4009C2CB0 /* ConnectableObservableType.swift in Sources */,
C8A56B5E1AD7435900B4673B /* Aggregate.swift in Sources */,
C8A56B531AD7435900B4673B /* AnonymousDisposable.swift in Sources */,
C8A56B671AD7435900B4673B /* Merge.swift in Sources */,
@ -902,6 +907,7 @@
C8A56B4F1AD7435900B4673B /* Lock.swift in Sources */,
C8A56B5C1AD7435900B4673B /* Observable.swift in Sources */,
C8A56B521AD7435900B4673B /* Disposable.swift in Sources */,
C8D675701B76BC26005264ED /* ConnectableObservableType.swift in Sources */,
C8A56B601AD7435900B4673B /* AsObservable.swift in Sources */,
C8A56B661AD7435900B4673B /* Do.swift in Sources */,
C8A56B591AD7435900B4673B /* SingleAssignmentDisposable.swift in Sources */,

View File

@ -8,6 +8,12 @@
import Foundation
extension Disposable {
public func addDisposableTo(bag: DisposeBag) {
bag.addDisposable(self)
}
}
// Thread safe bag that disposes disposables that have been added to it on `deinit`.
// This returns ARC (RAII) like resource management to `RxSwift`.
public class DisposeBag: DisposeBase {

View File

@ -8,9 +8,6 @@
import Foundation
@available(*, deprecated=1.5, message="NopDisposable")
typealias DefaultDisposable = NopDisposable
public let NopDisposableResult = success(NopDisposable.instance)
// Disposable that does nothing

View File

@ -8,6 +8,13 @@
import Foundation
extension Disposable {
public var scopedDispose: ScopedDispose {
return ScopedDispose(disposable: self)
}
}
// It will dispose `disposable` on `deinit`.
// This returns ARC (RAII) like resource management to `RxSwift`.
public class ScopedDispose : DisposeBase {
@ -25,8 +32,4 @@ public class ScopedDispose : DisposeBase {
deinit {
self.dispose()
}
}
public func scopedDispose(disposable: Disposable) -> ScopedDispose {
return ScopedDispose(disposable: disposable)
}

View File

@ -8,39 +8,32 @@
import Foundation
public func subscribe<E>
(on: (event: Event<E>) -> Void)
-> (Observable<E> -> Disposable) {
return { source in
extension ObservableType {
public func subscribe(on: (event: Event<E>) -> Void)
-> Disposable {
let observer = AnonymousObserver { e in
on(event: e)
}
return source.subscribeSafe(observer)
return self.subscribeSafe(observer)
}
}
public func subscribe<E>
(next: (E) -> Void, error: (ErrorType) -> Void, completed: () -> Void)
-> (Observable<E> -> Disposable) {
return { source in
public func subscribe(next: ((E) -> Void)? = nil, error: ((ErrorType) -> Void)? = nil, completed: (() -> Void)? = nil)
-> Disposable {
let observer = AnonymousObserver<E> { e in
switch e {
case .Next(let value):
next(value)
next?(value)
case .Error(let e):
error(e)
error?(e)
case .Completed:
completed()
completed?()
}
}
return source.subscribeSafe(observer)
return self.subscribeSafe(observer)
}
}
public func subscribeNext<E>
(onNext: (E) -> Void)
-> (Observable<E>) -> Disposable {
return { source in
public func subscribeNext(onNext: (E) -> Void)
-> Disposable {
let observer = AnonymousObserver<E> { e in
switch e {
case .Next(let value):
@ -49,14 +42,11 @@ public func subscribeNext<E>
break
}
}
return source.subscribeSafe(observer)
return self.subscribeSafe(observer)
}
}
public func subscribeError<E>
(onError: (ErrorType) -> Void)
-> (Observable<E> -> Disposable) {
return { source in
public func subscribeError(onError: (ErrorType) -> Void)
-> Disposable {
let observer = AnonymousObserver<E> { e in
switch e {
case .Error(let error):
@ -65,14 +55,11 @@ public func subscribeError<E>
break
}
}
return source.subscribeSafe(observer)
return self.subscribeSafe(observer)
}
}
public func subscribeCompleted<E>
(onCompleted: () -> Void)
-> (Observable<E> -> Disposable) {
return { source in
public func subscribeCompleted(onCompleted: () -> Void)
-> Disposable {
let observer = AnonymousObserver<E> { e in
switch e {
case .Completed:
@ -81,11 +68,11 @@ public func subscribeCompleted<E>
break
}
}
return source.subscribeSafe(observer)
return self.subscribeSafe(observer)
}
}
public extension Observable {
public extension ObservableType {
/*
Observables can really be anything, implemented by anyone and hooked into large `Observable` chains.
@ -101,7 +88,7 @@ public extension Observable {
`Producers` are special kind of observables that need to make sure that message grammar is respected.
*/
public func subscribeSafe<O: ObserverType where O.Element == Element>(observer: O) -> Disposable {
public func subscribeSafe<O: ObserverType where O.Element == E>(observer: O) -> Disposable {
if let source = self as? Producer<O.Element> {
return source.subscribeRaw(observer, enableSafeguard: false)
}

View File

@ -8,7 +8,9 @@
import Foundation
public class Observable<Element> {
public class Observable<Element> : ObservableType {
public typealias E = Element
public init() {
#if TRACE_RESOURCES
OSAtomicIncrement32(&resourceCount)
@ -16,14 +18,17 @@ public class Observable<Element> {
}
/// Subscribes `observer` to receive events from this observable
public func subscribe<O: ObserverType where O.Element == Element>(observer: O) -> Disposable {
public func subscribe<O: ObserverType where O.Element == E>(observer: O) -> Disposable {
return abstractMethod()
}
public func normalize() -> Observable<E> {
return self
}
deinit {
#if TRACE_RESOURCES
OSAtomicDecrement32(&resourceCount)
#endif
}
}

View File

@ -0,0 +1,18 @@
//
// ObservableType.swift
// RxSwift
//
// Created by Krunoslav Zaher on 8/8/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
public protocol ObservableType {
typealias E
/// Subscribes `observer` to receive events from this observable
func subscribe<O: ObserverType where O.Element == E>(observer: O) -> Disposable
func normalize() -> Observable<E>
}

View File

@ -40,7 +40,7 @@ class ConnectableObservable<SourceType, ResultType> : ConnectableObservableType<
var connection: ConnectionType?
init(source: Observable<SourceType>, subject: SubjectType<SourceType, ResultType>) {
self.source = asObservable(source)
self.source = source.asObservable()
self.subject = subject
self.connection = nil
}

View File

@ -40,7 +40,7 @@ class Debug<Element> : Producer<Element> {
let source: Observable<Element>
init(identifier: String, source: Observable<Element>) {
init(source: Observable<Element>, identifier: String) {
self.identifier = identifier
self.source = source
}

View File

@ -8,10 +8,10 @@
import Foundation
class Where_<O : ObserverType>: Sink<O>, ObserverType {
class FilterSink<O : ObserverType>: Sink<O>, ObserverType {
typealias Element = O.Element
typealias Parent = Where<Element>
typealias Parent = Filter<Element>
let parent: Parent
@ -41,7 +41,7 @@ class Where_<O : ObserverType>: Sink<O>, ObserverType {
}
}
class Where<Element> : Producer<Element> {
class Filter<Element> : Producer<Element> {
typealias Predicate = (Element) -> RxResult<Bool>
let source: Observable<Element>
@ -53,7 +53,7 @@ class Where<Element> : Producer<Element> {
}
override func run<O: ObserverType where O.Element == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = Where_(parent: self, observer: observer, cancel: cancel)
let sink = FilterSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return source.subscribeSafe(sink)
}

View File

@ -10,14 +10,15 @@ import Foundation
// sequential
class Merge_Iter<O: ObserverType> : ObserverType {
class MergeSinkIter<S: ObservableType, O: ObserverType where O.Element == S.E> : ObserverType {
typealias Element = O.Element
typealias DisposeKey = Bag<Disposable>.KeyType
typealias Parent = MergeSink<S, O>
let parent: Merge_<O>
let parent: Parent
let disposeKey: DisposeKey
init(parent: Merge_<O>, disposeKey: DisposeKey) {
init(parent: Parent, disposeKey: DisposeKey) {
self.parent = parent
self.disposeKey = disposeKey
}
@ -49,9 +50,9 @@ class Merge_Iter<O: ObserverType> : ObserverType {
}
}
class Merge_<O: ObserverType> : Sink<O>, ObserverType {
typealias Element = Observable<O.Element>
typealias Parent = Merge<O.Element>
class MergeSink<S: ObservableType, O: ObserverType where O.Element == S.E> : Sink<O>, ObserverType {
typealias Element = S
typealias Parent = Merge<S>
typealias MergeState = (
stopped: Bool,
@ -96,7 +97,7 @@ class Merge_<O: ObserverType> : Sink<O>, ObserverType {
let maybeKey = mergeState.group.addDisposable(innerSubscription)
if let key = maybeKey {
let observer = Merge_Iter(parent: self, disposeKey: key)
let observer = MergeSinkIter(parent: self, disposeKey: key)
let disposable = value.subscribeSafe(observer)
innerSubscription.disposable = disposable
}
@ -127,10 +128,10 @@ class Merge_<O: ObserverType> : Sink<O>, ObserverType {
// concurrent
class Merge_ConcurrentIter<O: ObserverType> : ObserverType {
class MergeConcurrentSinkIter<S: ObservableType, O: ObserverType where S.E == O.Element> : ObserverType {
typealias Element = O.Element
typealias DisposeKey = Bag<Disposable>.KeyType
typealias Parent = Merge_Concurrent<O>
typealias Parent = MergeConcurrentSink<S, O>
let parent: Parent
let disposeKey: DisposeKey
@ -173,10 +174,10 @@ class Merge_ConcurrentIter<O: ObserverType> : ObserverType {
}
}
class Merge_Concurrent<O: ObserverType> : Sink<O>, ObserverType {
typealias Element = Observable<O.Element>
typealias Parent = Merge<O.Element>
typealias QueueType = Queue<Observable<O.Element>>
class MergeConcurrentSink<S: ObservableType, O: ObserverType where S.E == O.Element> : Sink<O>, ObserverType {
typealias Element = S
typealias Parent = Merge<S>
typealias QueueType = Queue<S>
typealias MergeState = (
stopped: Bool,
@ -222,7 +223,7 @@ class Merge_Concurrent<O: ObserverType> : Sink<O>, ObserverType {
let key = group.addDisposable(subscription)
if let key = key {
let observer = Merge_ConcurrentIter(parent: self, disposeKey: key)
let observer = MergeConcurrentSinkIter(parent: self, disposeKey: key)
let disposable = innerSource.subscribeSafe(observer)
subscription.disposable = disposable
@ -272,23 +273,23 @@ class Merge_Concurrent<O: ObserverType> : Sink<O>, ObserverType {
}
}
class Merge<Element> : Producer<Element> {
let sources: Observable<Observable<Element>>
class Merge<S: ObservableType> : Producer<S.E> {
let sources: Observable<S>
let maxConcurrent: Int
init(sources: Observable<Observable<Element>>, maxConcurrent: Int) {
init(sources: Observable<S>, maxConcurrent: Int) {
self.sources = sources
self.maxConcurrent = maxConcurrent
}
override func run<O: ObserverType where O.Element == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
override func run<O: ObserverType where O.Element == S.E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
if maxConcurrent > 0 {
let sink = Merge_Concurrent(parent: self, observer: observer, cancel: cancel)
let sink = MergeConcurrentSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
}
else {
let sink = Merge_(parent: self, observer: observer, cancel: cancel)
let sink = MergeSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
}

View File

@ -8,9 +8,9 @@
import Foundation
class Switch_<O: ObserverType> : Sink<O>, ObserverType {
typealias Element = Observable<O.Element>
typealias Parent = Switch<O.Element>
class SwitchSink<S: ObservableType, O: ObserverType where S.E == O.Element> : Sink<O>, ObserverType {
typealias Element = S
typealias Parent = Switch<S>
typealias SwitchState = (
subscription: SingleAssignmentDisposable,
@ -49,14 +49,14 @@ class Switch_<O: ObserverType> : Sink<O>, ObserverType {
case .Next(let observable):
let latest: Int = self.lock.calculateLocked {
self.switchState.hasLatest = true
self.switchState.latest = self.switchState.latest + 1
self.switchState.latest = self.switchState.latest &+ 1
return self.switchState.latest
}
let d = SingleAssignmentDisposable()
self.switchState.innerSubscription.disposable = d
let observer = SwitchIter(parent: self, id: latest, _self: d)
let observer = SwitchSinkIter(parent: self, id: latest, _self: d)
let disposable = observable.subscribeSafe(observer)
d.disposable = disposable
case .Error(let error):
@ -79,9 +79,9 @@ class Switch_<O: ObserverType> : Sink<O>, ObserverType {
}
}
class SwitchIter<O: ObserverType> : ObserverType {
class SwitchSinkIter<S: ObservableType, O: ObserverType where S.E == O.Element> : ObserverType {
typealias Element = O.Element
typealias Parent = Switch_<O>
typealias Parent = SwitchSink<S, O>
let parent: Parent
let id: Int
@ -126,15 +126,15 @@ class SwitchIter<O: ObserverType> : ObserverType {
}
}
class Switch<Element> : Producer<Element> {
let sources: Observable<Observable<Element>>
class Switch<S: ObservableType> : Producer<S.E> {
let sources: Observable<S>
init(sources: Observable<Observable<Element>>) {
init(sources: Observable<S>) {
self.sources = sources
}
override func run<O : ObserverType where O.Element == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = Switch_(parent: self, observer: observer, cancel: cancel)
override func run<O : ObserverType where O.Element == S.E>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = SwitchSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
}

View File

@ -10,68 +10,56 @@ import Foundation
// aggregate
public func aggregateOrDie<E, A, R>
(seed: A, _ accumulator: (A, E) -> RxResult<A>, _ resultSelector: (A) -> RxResult<R>)
-> (Observable<E> -> Observable<R>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: accumulator, resultSelector: resultSelector)
extension ObservableType {
public func aggregateOrDie<A, R>
(seed: A, _ accumulator: (A, E) -> RxResult<A>, _ resultSelector: (A) -> RxResult<R>)
-> Observable<R> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: accumulator, resultSelector: resultSelector)
}
}
public func aggregateOrDie<E, A>
(seed: A, _ accumulator: (A, E) -> RxResult<A>)
-> (Observable<E> -> Observable<A>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: accumulator, resultSelector: { success($0) })
public func aggregateOrDie<A>
(seed: A, _ accumulator: (A, E) -> RxResult<A>)
-> Observable<A> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: accumulator, resultSelector: { success($0) })
}
}
public func aggregate<E, A, R>
(seed: A, _ accumulator: (A, E) -> A, _ resultSelector: (A) -> R)
-> (Observable<E> -> Observable<R>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success(resultSelector($0)) })
public func aggregate<A, R>
(seed: A, _ accumulator: (A, E) -> A, _ resultSelector: (A) -> R)
-> Observable<R> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success(resultSelector($0)) })
}
}
public func aggregate<E, A>
(seed: A, _ accumulator: (A, E) -> A)
-> (Observable<E> -> Observable<A>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success($0) })
public func aggregate<A>
(seed: A, _ accumulator: (A, E) -> A)
-> Observable<A> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success($0) })
}
}
// reduce
public func reduceOrDie<E, A, R>
(seed: A, _ accumulator: (A, E) -> RxResult<A>, _ resultSelector: (A) -> RxResult<R>)
-> (Observable<E> -> Observable<R>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: accumulator, resultSelector: resultSelector)
extension ObservableType {
public func reduceOrDie<A, R>
(seed: A, _ accumulator: (A, E) -> RxResult<A>, _ resultSelector: (A) -> RxResult<R>)
-> Observable<R> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: accumulator, resultSelector: resultSelector)
}
public func reduceOrDie<A>
(seed: A, _ accumulator: (A, E) -> RxResult<A>)
-> Observable<A> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: accumulator, resultSelector: { success($0) })
}
public func reduce<A, R>
(seed: A, _ accumulator: (A, E) -> A, _ resultSelector: (A) -> R)
-> Observable<R> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success(resultSelector($0)) })
}
public func reduce<A>
(seed: A, _ accumulator: (A, E) -> A)
-> Observable<A> {
return Aggregate(source: self.normalize(), seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success($0) })
}
}
public func reduceOrDie<E, A>
(seed: A, _ accumulator: (A, E) -> RxResult<A>)
-> (Observable<E> -> Observable<A>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: accumulator, resultSelector: { success($0) })
}
}
public func reduce<E, A, R>
(seed: A, _ accumulator: (A, E) -> A, _ resultSelector: (A) -> R)
-> (Observable<E> -> Observable<R>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success(resultSelector($0)) })
}
}
public func reduce<E, A>
(seed: A, _ accumulator: (A, E) -> A)
-> (Observable<E> -> Observable<A>) {
return { source in
return Aggregate(source: source, seed: seed, accumulator: { success(accumulator($0, $1)) }, resultSelector: { success($0) })
}
}

View File

@ -10,87 +10,86 @@ import Foundation
// multicast
public func multicast<E, R>
(subject: SubjectType<E, R>)
-> (Observable<E> -> ConnectableObservableType<R>) {
return { source in
return ConnectableObservable(source: source, subject: subject)
extension ObservableType {
public func multicast<R>(subject: SubjectType<E, R>)
-> ConnectableObservableType<R> {
return ConnectableObservable(source: self.normalize(), subject: subject)
}
}
public func multicastOrDie<E, I, R>
(
subjectSelector: () -> RxResult<SubjectType<E, I>>,
selector: (Observable<I>) -> RxResult<Observable<R>>
)
-> (Observable<E> -> Observable<R>) {
return { source in
public func multicastOrDie<I, R>(
subjectSelector: () -> RxResult<SubjectType<E, I>>,
selector: (Observable<I>) -> RxResult<Observable<R>>
)
-> Observable<R> {
return Multicast(
source: source,
source: self.normalize(),
subjectSelector: subjectSelector,
selector: selector
)
}
}
public func multicast<E, I, R>
(
subjectSelector: () -> SubjectType<E, I>,
selector: (Observable<I>) -> Observable<R>
)
-> (Observable<E> -> Observable<R>) {
return { source in
return Multicast(
source: source,
subjectSelector: { success(subjectSelector()) },
selector: { success(selector($0)) }
)
}
public func multicast<I, R>
(
subjectSelector: () -> SubjectType<E, I>,
selector: (Observable<I>) -> Observable<R>
)
-> Observable<R> {
return Multicast(
source: self.normalize(),
subjectSelector: { success(subjectSelector()) },
selector: { success(selector($0)) }
)
}
}
// publish
public func publish<E>(source: Observable<E>)
-> ConnectableObservableType<E> {
return source >- multicast(PublishSubject())
extension ObservableType {
public var publish: ConnectableObservableType<E> {
return self.multicast(PublishSubject())
}
}
// replay
// replay
public func replay<E>
(bufferSize: Int)
-> (Observable<E> -> ConnectableObservableType<E>) {
return { source in
return multicast(ReplaySubject(bufferSize: bufferSize))(source)
extension ObservableType {
public func replay(bufferSize: Int)
-> ConnectableObservableType<E> {
return self.multicast(ReplaySubject(bufferSize: bufferSize))
}
}
// refcount
public func refCount<E>
(source: ConnectableObservableType<E>)
-> Observable<E> {
return RefCount(source: source)
extension ConnectableObservableType {
public var refCount: Observable<E> {
return RefCount(source: self)
}
}
// sharedWithCachedLastResult
// share
// In Rx every subscription uses it's own set of resources.
// In case of UI, asynchronous operations are usually used to fetch data from server.
// In case data is fetched from server, stale data can be served first, and then updated with
// fresh data from server.
extension ObservableType {
public var share: Observable<E> {
return self.publish.refCount
}
}
public func sharedWithCachedLastResult<E>(source: Observable<E>)
-> Observable<E> {
return source >- replay(1) >- refCount
// shareReplay
extension ObservableType {
public func shareReplay(bufferSize: Int)
-> Observable<E> {
return self.replay(bufferSize).refCount
}
}
// variable
// variable is synonym for `sharedWithCachedLastResult`
public func variable<E>(source: Observable<E>)
-> Observable<E> {
return source >- replay(1) >- refCount
extension ObservableType {
// variable is alias for `shareReplay(1)`
public var variable: Observable<E> {
return self.replay(1).refCount
}
}

View File

@ -8,38 +8,42 @@
import Foundation
// `observeSingleOn` assumes that observed sequence will have one element
// and in cases it has more than one element it will throw an exception.
//
// Most common use case for `observeSingleOn` would be to execute some work on background thread
// and return result to main thread.
//
// This is a performance gain considering general case.
public func observeSingleOn<E>
(scheduler: ImmediateScheduler)
-> Observable<E> -> Observable<E> {
return { source in
return ObserveSingleOn(source: source, scheduler: scheduler)
// observeOnSingle
extension ObservableType {
// `observeSingleOn` assumes that observed sequence will have one element
// and in cases it has more than one element it will throw an exception.
//
// Most common use case for `observeSingleOn` would be to execute some work on background thread
// and return result to main thread.
//
// This is a performance gain considering general case.
public func observeSingleOn(scheduler: ImmediateScheduler)
-> Observable<E> {
return ObserveSingleOn(source: self.normalize(), scheduler: scheduler)
}
}
public func observeOn<E>
(scheduler: ImmediateScheduler)
-> Observable<E> -> Observable<E> {
return { source in
// observeOn
extension ObservableType {
public func observeOn(scheduler: ImmediateScheduler)
-> Observable<E> {
if let scheduler = scheduler as? SerialDispatchQueueScheduler {
return ObserveOnSerialDispatchQueue(source: source, scheduler: scheduler)
return ObserveOnSerialDispatchQueue(source: self.normalize(), scheduler: scheduler)
}
else {
return ObserveOn(source: source, scheduler: scheduler)
return ObserveOn(source: self.normalize(), scheduler: scheduler)
}
}
}
public func subscribeOn<E>
(scheduler: ImmediateScheduler)
-> Observable<E> -> Observable<E> {
return { source in
return SubscribeOn(source: source, scheduler: scheduler)
// subscribeOn
extension ObservableType {
public func subscribeOn(scheduler: ImmediateScheduler)
-> Observable<E> {
return SubscribeOn(source: self.normalize(), scheduler: scheduler)
}
}

View File

@ -33,7 +33,7 @@ public func never<E>() -> Observable<E> {
// return
public func returnElement<E>(value: E) -> Observable<E> {
public func just<E>(value: E) -> Observable<E> {
return AnonymousObservable { observer in
sendNext(observer, value)
sendCompleted(observer)
@ -41,11 +41,7 @@ public func returnElement<E>(value: E) -> Observable<E> {
}
}
public func just<E>(value: E) -> Observable<E> {
return returnElement(value)
}
public func returnElements<E>(values: E ...) -> Observable<E> {
public func sequence<E>(values: E ...) -> Observable<E> {
return AnonymousObservable { observer in
for element in values {
sendNext(observer, element)

View File

@ -10,9 +10,9 @@ import Foundation
// debug
public func debug<E>(identifier: String)
-> (Observable<E> -> Observable<E>) {
return { source in
return Debug(identifier: identifier, source: source)
extension ObservableType {
public func debug(identifier: String)
-> Observable<E> {
return Debug(source: self.normalize(), identifier: identifier)
}
}

View File

@ -10,110 +10,92 @@ import Foundation
// switch
public func switchLatest<T>
(sources: Observable<Observable<T>>)
-> Observable<T> {
// swift doesn't have co/contravariance
return Switch(sources: sources)
extension ObservableType where E : ObservableType {
public var switchLatest: Observable<E.E> {
// swift doesn't have co/contravariance
return Switch(sources: self.normalize())
}
}
// concat
public func concat<E>
(sources: [Observable<E>])
-> Observable<E> {
return Concat(sources: sources)
public func concat<O: ObservableType>(sources: [O])
-> Observable<O.E> {
return Concat(sources: LazySequence(sources).map { $0.normalize() })
}
public func concat<E>
(sources: Observable<Observable<E>>)
-> Observable<E> {
return merge(maxConcurrent: 1)(sources)
extension ObservableType where E : ObservableType {
public var concat: Observable<E.E> {
return self.merge(maxConcurrent: 1)
}
}
// merge
public func merge<E>
(sources: Observable<Observable<E>>)
-> Observable<E> {
return Merge(sources: sources, maxConcurrent: 0)
}
extension ObservableType where E : ObservableType {
public var merge: Observable<E.E> {
return Merge(sources: self.normalize(), maxConcurrent: 0)
}
public func merge<E>
(maxConcurrent maxConcurrent: Int)
-> (Observable<Observable<E>> -> Observable<E>) {
return { sources in
return Merge(sources: sources, maxConcurrent: maxConcurrent)
public func merge(maxConcurrent maxConcurrent: Int)
-> Observable<E.E> {
return Merge(sources: self.normalize(), maxConcurrent: maxConcurrent)
}
}
// catch
public func catchOrDie<E>
(handler: (ErrorType) -> RxResult<Observable<E>>)
-> (Observable<E> -> Observable<E>) {
return { source in
return Catch(source: source, handler: handler)
extension ObservableType {
public func catchErrorOrDie(handler: (ErrorType) -> RxResult<Observable<E>>)
-> Observable<E> {
return Catch(source: self.normalize(), handler: handler)
}
public func catchError(handler: (ErrorType) -> Observable<E>)
-> Observable<E> {
return Catch(source: self.normalize(), handler: { success(handler($0)) })
}
// In case of error, terminates sequence with `replaceErrorWith`.
public func catchError(replaceErrorWith: E)
-> Observable<E> {
return Catch(source: self.normalize(), handler: { _ in success(just(replaceErrorWith)) })
}
// When error happens `error` will be forwarded as a next `Result<E>` value
// and sequence will be completed.
public var catchErrorToResult: Observable <RxResult<E>> {
return CatchToResult(source: self.normalize())
}
}
public func onError<E>
(handler: (ErrorType) -> Observable<E>)
-> (Observable<E> -> Observable<E>) {
return { source in
return Catch(source: source, handler: { success(handler($0)) })
}
}
public func onError<E>
(sources: AnySequence<Observable<E>>)
public func catchError<E>(sources: AnySequence<Observable<E>>)
-> Observable<E> {
// just wrapping it in sequence of for now
return CatchSequence(sources: AnySequence(sources))
}
// In case of error, terminates sequence with `replaceErrorWith`.
public func onError<E>
(replaceErrorWith: E)
-> (Observable<E> -> Observable<E>) {
return { source in
return Catch(source: source, handler: { _ in success(returnElement(replaceErrorWith)) })
}
}
// When error happens `error` will be forwarded as a next `Result<E>` value
// and sequence will be completed.
public func catchToResult<E>
(source: Observable<E>)
-> Observable <RxResult<E>> {
return CatchToResult(source: source)
return CatchSequence(sources: sources)
}
// takeUntil
public func takeUntil<E, O>
(other: Observable<O>)
-> Observable<E> -> Observable<E> {
return { source in
return TakeUntil(source: source, other: other)
extension ObservableType {
public func takeUntil<O: ObservableType>(other: O)
-> Observable<E> {
return TakeUntil(source: self.normalize(), other: other.normalize())
}
}
// amb
// amb
public func amb<E>
(left: Observable<E>, _ right: Observable<E>)
-> Observable<E> {
return Amb(left: left, right: right)
public func amb<O: ObservableType>
(left: O, _ right: O)
-> Observable<O.E> {
return Amb(left: left.normalize(), right: right.normalize())
}
public func amb<E>
(observables: AnySequence<Observable<E>>)
-> Observable<E> {
public func amb<O: ObservableType>
(observables: AnySequence<O>)
-> Observable<O.E> {
return observables.reduce(never()) { a, o in
return amb(a, o)
return amb(a, o.normalize())
}
}

View File

@ -10,102 +10,83 @@ import Foundation
// as observable
public func asObservable<E>
(source: Observable<E>) -> Observable<E> {
if let asObservable = source as? AsObservable<E> {
return asObservable.omega()
}
else {
return AsObservable(source: source)
extension ObservableType {
public func asObservable() -> Observable<E> {
if let asObservable = self as? AsObservable<E> {
return asObservable.omega()
}
else {
return AsObservable(source: self.normalize())
}
}
}
// distinct until changed
public func distinctUntilChangedOrDie<E: Equatable>(source: Observable<E>)
-> Observable<E> {
return distinctUntilChangedOrDie({ success($0) }, { success($0 == $1) })(source)
}
extension ObservableType where E: Equatable {
public func distinctUntilChangedOrDie()
-> Observable<E> {
return self.distinctUntilChangedOrDie({ success($0) }, { success($0 == $1) })
}
public func distinctUntilChangedOrDie<E, K: Equatable>
(keySelector: (E) -> RxResult<K>)
-> (Observable<E> -> Observable<E>) {
return { source in
return distinctUntilChangedOrDie(keySelector, { success($0 == $1) })(source)
public func distinctUntilChanged()
-> Observable<E> {
return self.distinctUntilChanged({ $0 }, { ($0 == $1) })
}
}
public func distinctUntilChangedOrDie<E>
(comparer: (lhs: E, rhs: E) -> RxResult<Bool>)
-> (Observable<E> -> Observable<E>) {
return { source in
return distinctUntilChangedOrDie({ success($0) }, comparer)(source)
extension ObservableType {
public func distinctUntilChangedOrDie<K: Equatable>(keySelector: (E) -> RxResult<K>)
-> Observable<E> {
return self.distinctUntilChangedOrDie(keySelector, { success($0 == $1) })
}
}
public func distinctUntilChangedOrDie<E, K>
(keySelector: (E) -> RxResult<K>, _ comparer: (lhs: K, rhs: K) -> RxResult<Bool>)
-> (Observable<E> -> Observable<E>) {
return { source in
return DistinctUntilChanged(source: source, selector: keySelector, comparer: comparer)
public func distinctUntilChangedOrDie(comparer: (lhs: E, rhs: E) -> RxResult<Bool>)
-> Observable<E> {
return self.distinctUntilChangedOrDie({ success($0) }, comparer)
}
}
public func distinctUntilChanged<E: Equatable>(source: Observable<E>)
-> Observable<E> {
return distinctUntilChanged({ $0 }, { ($0 == $1) })(source)
}
public func distinctUntilChanged<E, K: Equatable>
(keySelector: (E) -> K)
-> (Observable<E> -> Observable<E>) {
return { source in
return distinctUntilChanged(keySelector, { ($0 == $1) })(source)
public func distinctUntilChangedOrDie<K>(keySelector: (E) -> RxResult<K>, _ comparer: (lhs: K, rhs: K) -> RxResult<Bool>)
-> Observable<E> {
return DistinctUntilChanged(source: self.normalize(), selector: keySelector, comparer: comparer)
}
}
public func distinctUntilChanged<E>
(comparer: (lhs: E, rhs: E) -> Bool)
-> (Observable<E> -> Observable<E>) {
return { source in
return distinctUntilChanged({ ($0) }, comparer)(source)
public func distinctUntilChanged<K: Equatable>(keySelector: (E) -> K)
-> Observable<E> {
return distinctUntilChanged(keySelector, { ($0 == $1) })
}
}
public func distinctUntilChanged<E, K>
(keySelector: (E) -> K, _ comparer: (lhs: K, rhs: K) -> Bool)
-> (Observable<E> -> Observable<E>) {
return { source in
return DistinctUntilChanged(source: source, selector: {success(keySelector($0)) }, comparer: { success(comparer(lhs: $0, rhs: $1))})
public func distinctUntilChanged(comparer: (lhs: E, rhs: E) -> Bool)
-> Observable<E> {
return distinctUntilChanged({ ($0) }, comparer)
}
public func distinctUntilChanged<K>(keySelector: (E) -> K, _ comparer: (lhs: K, rhs: K) -> Bool)
-> Observable<E> {
return DistinctUntilChanged(source: self.normalize(), selector: {success(keySelector($0)) }, comparer: { success(comparer(lhs: $0, rhs: $1))})
}
}
// do
public func doOrDie<E>
(eventHandler: (Event<E>) -> RxResult<Void>)
-> (Observable<E> -> Observable<E>) {
return { source in
return Do(source: source, eventHandler: eventHandler)
extension ObservableType {
public func doOrDie(eventHandler: (Event<E>) -> RxResult<Void>)
-> Observable<E> {
return Do(source: self.normalize(), eventHandler: eventHandler)
}
}
public func `do`<E>
(eventHandler: (Event<E>) -> Void)
-> (Observable<E> -> Observable<E>) {
return { source in
return Do(source: source, eventHandler: { success(eventHandler($0)) })
public func `do`(eventHandler: (Event<E>) -> Void)
-> Observable<E> {
return Do(source: self.normalize(), eventHandler: { success(eventHandler($0)) })
}
}
// doOnNext
public func doOnNext<E>
(actionOnNext: E -> Void)
-> (Observable<E> -> Observable<E>) {
return { source in
return source >- `do` { event in
extension ObservableType {
public func doOnNext(actionOnNext: E -> Void)
-> Observable<E> {
return self.`do` { event in
switch event {
case .Next(let value):
actionOnNext(value)
@ -118,47 +99,39 @@ public func doOnNext<E>
// startWith
// Prefixes observable sequence with `firstElement` element.
// The same functionality could be achieved using `concat([returnElement(prefix), source])`,
// but this is significantly more efficient implementation.
public func startWith<E>
(firstElement: E)
-> (Observable<E> -> Observable<E>) {
return { source in
return StartWith(source: source, element: firstElement)
extension ObservableType {
// Prefixes observable sequence with `firstElement` element.
// The same functionality could be achieved using `concat([just(prefix), source])`,
// but this is significantly more efficient implementation.
public func startWith(firstElement: E)
-> Observable<E> {
return StartWith(source: self.normalize(), element: firstElement)
}
}
// retry
public func retry<E>
(source: Observable<E>)
-> Observable<E> {
return AnySequence(InifiniteSequence(repeatedValue: source)) >- onError
}
extension ObservableType {
public var retry: Observable<E> {
return CatchSequence(sources: AnySequence(InifiniteSequence(repeatedValue: self.normalize())))
}
public func retry<E>
(retryCount: Int)
-> Observable<E> -> Observable<E> {
return { source in
return AnySequence(Repeat(count: retryCount, repeatedValue: source)) >- onError
public func retry(retryCount: Int)
-> Observable<E> {
return CatchSequence(sources: AnySequence(Repeat(count: retryCount, repeatedValue: self.normalize())))
}
}
// scan
public func scan<E, A>
(seed: A, accumulator: (A, E) -> A)
-> Observable<E> -> Observable<A> {
return { source in
return Scan(source: source, seed: seed, accumulator: { success(accumulator($0, $1)) })
extension ObservableType {
public func scan<A>(seed: A, accumulator: (A, E) -> A)
-> Observable<A> {
return Scan(source: self.normalize(), seed: seed, accumulator: { success(accumulator($0, $1)) })
}
}
public func scanOrDie<E, A>
(seed: A, accumulator: (A, E) -> RxResult<A>)
-> Observable<E> -> Observable<A> {
return { source in
return Scan(source: source, seed: seed, accumulator: accumulator)
public func scanOrDie<A>(seed: A, accumulator: (A, E) -> RxResult<A>)
-> Observable<A> {
return Scan(source: self.normalize(), seed: seed, accumulator: accumulator)
}
}

View File

@ -10,179 +10,99 @@ import Foundation
// filter aka where
public func filterOrDie<E>
(predicate: (E) -> RxResult<Bool>)
-> (Observable<E> -> Observable<E>) {
return { source in
return whereOrDie(predicate)(source)
extension ObservableType {
public func filterOrDie(predicate: (E) -> RxResult<Bool>)
-> Observable<E> {
return Filter(source: self.normalize(), predicate: predicate)
}
}
public func filter<E>
(predicate: (E) -> Bool)
-> (Observable<E> -> Observable<E>) {
return { source in
return `where`(predicate)(source)
}
}
public func whereOrDie<E>
(predicate: (E) -> RxResult<Bool>)
-> (Observable<E> -> Observable<E>) {
return { source in
return Where(source: source, predicate: predicate)
}
}
public func `where`<E>
(predicate: (E) -> Bool)
-> (Observable<E> -> Observable<E>) {
return { source in
return Where(source: source, predicate: { success(predicate($0)) })
public func filter(predicate: (E) -> Bool)
-> Observable<E> {
return Filter(source: self.normalize(), predicate: { success(predicate($0)) })
}
}
// takeWhile
public func takeWhile<E>
(predicate: (E) -> Bool)
-> (Observable<E> -> Observable<E>) {
return { source in
return TakeWhile(source: source, predicate: predicate)
extension ObservableType {
public func takeWhile(predicate: (E) -> Bool)
-> Observable<E> {
return TakeWhile(source: self.normalize(), predicate: predicate)
}
}
public func takeWhile<E>
(predicate: (E, Int) -> Bool)
-> (Observable<E> -> Observable<E>) {
return { source in
return TakeWhile(source: source, predicate: predicate)
public func takeWhile(predicate: (E, Int) -> Bool)
-> Observable<E> {
return TakeWhile(source: self.normalize(), predicate: predicate)
}
}
// take
public func take<E>
(count: Int)
-> Observable<E> -> Observable<E> {
return { source in
extension ObservableType {
public func take(count: Int)
-> Observable<E> {
if count == 0 {
return empty()
}
else {
return TakeCount(source: source, count: count)
return TakeCount(source: self.normalize(), count: count)
}
}
}
// skip
public func skip<E>
(count: Int)
-> Observable<E> -> Observable<E> {
return { source in
return SkipCount(source: source, count: count)
extension ObservableType {
public func skip(count: Int)
-> Observable<E> {
return SkipCount(source: self.normalize(), count: count)
}
}
// map aka select
public func mapOrDie<E, R>
(selector: E -> RxResult<R>)
-> (Observable<E> -> Observable<R>) {
return { source in
return selectOrDie(selector)(source)
extension ObservableType {
public func mapOrDie<R>(selector: E -> RxResult<R>)
-> Observable<R> {
return Map(source: self.normalize(), selector: selector)
}
public func map<R>(selector: E -> R)
-> Observable<R> {
return Map(source: self.normalize(), selector: { success(selector($0)) })
}
public func mapWithIndexOrDie<R>(selector: (E, Int) -> RxResult<R>)
-> Observable<R> {
return Map(source: self.normalize(), selector: selector)
}
public func mapWithIndex<R>(selector: (E, Int) -> R)
-> Observable<R> {
return Map(source: self.normalize(), selector: { success(selector($0, $1)) })
}
}
public func map<E, R>
(selector: E -> R)
-> (Observable<E> -> Observable<R>) {
return { source in
return select(selector)(source)
}
}
public func mapWithIndexOrDie<E, R>
(selector: (E, Int) -> RxResult<R>)
-> (Observable<E> -> Observable<R>) {
return { source in
return selectWithIndexOrDie(selector)(source)
}
}
public func mapWithIndex<E, R>
(selector: (E, Int) -> R)
-> (Observable<E> -> Observable<R>) {
return { source in
return selectWithIndex(selector)(source)
}
}
// select
public func selectOrDie<E, R>
(selector: (E) -> RxResult<R>)
-> (Observable<E> -> Observable<R>) {
return { source in
return Map(source: source, selector: selector)
}
}
public func select<E, R>
(selector: (E) -> R)
-> (Observable<E> -> Observable<R>) {
return { source in
return Map(source: source, selector: {success(selector($0)) })
}
}
public func selectWithIndexOrDie<E, R>
(selector: (E, Int) -> RxResult<R>)
-> (Observable<E> -> Observable<R>) {
return { source in
return Map(source: source, selector: selector)
}
}
public func selectWithIndex<E, R>
(selector: (E, Int) -> R)
-> (Observable<E> -> Observable<R>) {
return { source in
return Map(source: source, selector: {success(selector($0, $1)) })
}
}
// flatMap
public func flatMap<E, R>
(selector: (E) -> Observable<R>)
-> Observable<E> -> Observable<R> {
return { source in
return FlatMap(source: source, selector: { success(selector($0)) })
extension ObservableType {
public func flatMap<R>(selector: (E) -> Observable<R>)
-> Observable<R> {
return FlatMap(source: self.normalize(), selector: { success(selector($0)) })
}
}
public func flatMapOrDie<E, R>
(selector: (E) -> RxResult<Observable<R>>)
-> Observable<E> -> Observable<R> {
return { source in
return FlatMap(source: source, selector: selector)
public func flatMapOrDie<R>(selector: (E) -> RxResult<Observable<R>>)
-> Observable<R> {
return FlatMap(source: self.normalize(), selector: selector)
}
}
public func flatMapWithIndex<E, R>
(selector: (E, Int) -> Observable<R>)
-> Observable<E> -> Observable<R> {
return { source in
return FlatMap(source: source, selector: { success(selector($0, $1)) })
public func flatMapWithIndex<R>(selector: (E, Int) -> Observable<R>)
-> Observable<R> {
return FlatMap(source: self.normalize(), selector: { success(selector($0, $1)) })
}
}
public func flatMapWithIndexOrDie<E, R>
(selector: (E, Int) -> RxResult<Observable<R>>)
-> Observable<E> -> Observable<R> {
return { source in
return FlatMap(source: source, selector: selector)
public func flatMapWithIndexOrDie<R>(selector: (E, Int) -> RxResult<Observable<R>>)
-> Observable<R> {
return FlatMap(source: self.normalize(), selector: selector)
}
}

View File

@ -9,70 +9,61 @@
import Foundation
// throttle
public func throttle<E, S: Scheduler>
(dueTime: S.TimeInterval, _ scheduler: S)
-> (Observable<E> -> Observable<E>) {
return { source in
return Throttle(source: source, dueTime: dueTime, scheduler: scheduler)
extension ObservableType {
public func throttle<S: Scheduler>(dueTime: S.TimeInterval, _ scheduler: S)
-> Observable<E> {
return Throttle(source: self.normalize(), dueTime: dueTime, scheduler: scheduler)
}
}
public func debounce<E, S: Scheduler>
(dueTime: S.TimeInterval, scheduler: S)
-> (Observable<E> -> Observable<E>) {
return { source in
return Throttle(source: source, dueTime: dueTime, scheduler: scheduler)
public func debounce<S: Scheduler>(dueTime: S.TimeInterval, scheduler: S)
-> Observable<E> {
return Throttle(source: self.normalize(), dueTime: dueTime, scheduler: scheduler)
}
}
// sample
// If there isn't a new value in `source` sequence from the last sample time
// nothing will be forwarded.
public func sample<E, S>
(sampler: Observable<S>)
-> (Observable<E> -> Observable<E>) {
return { source in
return Sample(source: source, sampler: sampler, onlyNew: true)
extension ObservableType {
// If there isn't a new value in `source` sequence from the last sample time
// nothing will be forwarded.
public func sample<S>(sampler: Observable<S>)
-> Observable<E> {
return Sample(source: self.normalize(), sampler: sampler, onlyNew: true)
}
}
// On each sample latest element will always be forwarded.
public func sampleLatest<E, S>
(sampler: Observable<S>)
-> (Observable<E> -> Observable<E>) {
return { source in
return Sample(source: source, sampler: sampler, onlyNew: false)
// On each sample latest element will always be forwarded.
public func sampleLatest<S>(sampler: Observable<S>)
-> Observable<E> {
return Sample(source: self.normalize(), sampler: sampler, onlyNew: false)
}
}
// interval
// fallback {
public func interval<S: Scheduler>
(period: S.TimeInterval, _ scheduler: S)
public func interval<S: Scheduler>(period: S.TimeInterval, _ scheduler: S)
-> Observable<Int64> {
return Timer(dueTime: period,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
return Timer(dueTime: period,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
}
// }
// periodic schedulers {
public func interval<S: PeriodicScheduler>
(period: S.TimeInterval, _ scheduler: S)
public func interval<S: PeriodicScheduler>(period: S.TimeInterval, _ scheduler: S)
-> Observable<Int64> {
return Timer(dueTime: period,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
return Timer(dueTime: period,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
}
// }
@ -81,83 +72,76 @@ public func interval<S: PeriodicScheduler>
// fallback {
public func timer<S: Scheduler>
(dueTime: S.TimeInterval, _ period: S.TimeInterval, scheduler: S)
public func timer<S: Scheduler>(dueTime: S.TimeInterval, _ period: S.TimeInterval, scheduler: S)
-> Observable<Int64> {
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
}
public func timer<S: Scheduler>
(dueTime: S.TimeInterval, scheduler: S)
public func timer<S: Scheduler>(dueTime: S.TimeInterval, scheduler: S)
-> Observable<Int64> {
return Timer(
dueTime: dueTime,
period: nil,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
return Timer(
dueTime: dueTime,
period: nil,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
}
// }
// periodic schedulers {
public func timer<S: PeriodicScheduler>
(dueTime: S.TimeInterval, _ period: S.TimeInterval, scheduler: S)
public func timer<S: PeriodicScheduler>(dueTime: S.TimeInterval, _ period: S.TimeInterval, scheduler: S)
-> Observable<Int64> {
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
}
public func timer<S: PeriodicScheduler>
(dueTime: S.TimeInterval, scheduler: S)
public func timer<S: PeriodicScheduler>(dueTime: S.TimeInterval, scheduler: S)
-> Observable<Int64> {
return Timer(
dueTime: dueTime,
period: nil,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
return Timer(
dueTime: dueTime,
period: nil,
scheduler: scheduler,
schedulePeriodic: abstractSchedulePeriodic(scheduler)
)
}
// }
// take
public func take<E, S: Scheduler>
(duration: S.TimeInterval, _ scheduler: S)
-> Observable<E> -> Observable<E> {
return { source in
return TakeTime(source: source, duration: duration, scheduler: scheduler)
extension ObservableType {
public func take<S: Scheduler>(duration: S.TimeInterval, _ scheduler: S)
-> Observable<E> {
return TakeTime(source: self.normalize(), duration: duration, scheduler: scheduler)
}
}
// skip
public func skip<E, S: Scheduler>
(duration: S.TimeInterval, _ scheduler: S)
-> Observable<E> -> Observable<E> {
return { source in
return SkipTime(source: source, duration: duration, scheduler: scheduler)
extension ObservableType {
public func skip<S: Scheduler>(duration: S.TimeInterval, _ scheduler: S)
-> Observable<E> {
return SkipTime(source: self.normalize(), duration: duration, scheduler: scheduler)
}
}
// delaySubscription
public func delaySubscription<E, S: Scheduler>
(dueTime: S.TimeInterval, _ scheduler: S)
-> Observable<E> -> Observable<E> {
return { source in
return DelaySubscription(source: source, dueTime: dueTime, scheduler: scheduler)
extension ObservableType {
public func delaySubscription<S: Scheduler>(dueTime: S.TimeInterval, _ scheduler: S)
-> Observable<E> {
return DelaySubscription(source: self.normalize(), dueTime: dueTime, scheduler: scheduler)
}
}

View File

@ -20,19 +20,6 @@ public var resourceCount: Int32 = 0
public var numberOfSerialDispatchQueueObservables: Int32 = 0
#endif
// This is the pipe operator (left associative function application operator)
// a >- b >- c == c(b(a))
// The reason this one is chosen for now is because
// * It's subtle, doesn't add a lot of visual noise
// * It's short
// * It kind of looks like ASCII art horizontal sink to the right
//
infix operator >- { associativity left precedence 91 }
public func >- <In, Out>(lhs: In, @noescape rhs: In -> Out) -> Out {
return rhs(lhs)
}
func contract(@autoclosure condition: () -> Bool) {
if !condition() {
let exception = NSException(name: "ContractError", reason: "Contract failed", userInfo: nil)

View File

@ -187,90 +187,3 @@ func lift<T1, T2, T3, TRet>(function: (T1, T2, T3) -> TRet) -> (RxResult<T1>, Rx
}
}
// depricated
@available(*, deprecated=1.4, message="Replaced by success")
public func `return`<T>(value: T) -> RxResult<T> {
return .Success(value)
}
infix operator >== { associativity left precedence 95 }
@available(*, deprecated=1.4, message="Replaced by flatMap")
public func >== <In, Out>(lhs: RxResult<In>, @noescape rhs: (In) -> RxResult<Out>) -> RxResult<Out> {
switch lhs {
case .Success(let result): return rhs(result)
case .Failure(let error): return .Failure(error)
}
}
@available(*, deprecated=1.4, message="Replaced by map")
public func >== <In, Out>(lhs: RxResult<In>, @noescape rhs: (In) -> Out) -> RxResult<Out> {
switch lhs {
case .Success(let result): return success(rhs(result))
case .Failure(let error): return .Failure(error)
}
}
infix operator >>> { associativity left precedence 95 }
@available(*, deprecated=1.4, message="Replaced by map")
public func >>> <In, Out>(lhs: RxResult<In>, @noescape rhs: () -> Out) -> RxResult<Out> {
switch lhs {
case .Success: return success(rhs())
case .Failure(let error): return .Failure(error)
}
}
@available(*, deprecated=1.4, message="Replaced by flatMap")
public func >>> <In, Out>(lhs: RxResult<In>, @noescape rhs: () -> RxResult<Out>) -> RxResult<Out> {
switch lhs {
case .Success: return rhs()
case .Failure(let error): return .Failure(error)
}
}
infix operator >>! { associativity left precedence 95 }
@available(*, deprecated=1.4, message="Replaced by recoverWith")
public func >>! <In>(lhs: RxResult<In>, @noescape rhs: (ErrorType) -> RxResult<In>) -> RxResult<In> {
switch lhs {
case .Failure(let error):
return rhs(error)
default:
return lhs
}
}
prefix operator * { }
@available(*, deprecated=1.4, message="Replaced by get")
public prefix func *<T>(result: RxResult<T>) -> T {
switch result {
case .Success(let value): return value
default:
let result: T? = nil
return result!
}
}
@available(*, deprecated=1.4, message="Replaced by recover")
public func replaceErrorWith<T>(result: RxResult<T>, errorValue: T) -> T {
switch result {
case .Success(let value):
return value
case .Failure:
return errorValue
}
}
@available(*, deprecated=1.4, message="Replaced by recoverWith")
public func replaceErrorWithNil<T>(result: RxResult<T>) -> T? {
switch result {
case .Success(let value):
return value
case .Failure:
return nil
}
}

View File

@ -8,9 +8,6 @@
import Foundation
@available(*, deprecated=1.7, message="Replaced by `SerialDispatchQueueScheduler`")
public typealias DispatchQueueScheduler = SerialDispatchQueueScheduler
// This is a scheduler that wraps dispatch queue.
// It can wrap both serial and concurrent dispatch queues.
//

View File

@ -34,14 +34,6 @@ class Subscription<Element> : Disposable {
}
}
@available(*, deprecated=1.7, message="Replaced by PublishSubject")
public class Subject<Element> : PublishSubject<Element> {
public override init() {
super.init()
}
}
public class PublishSubject<Element> : SubjectType<Element, Element>, Cancelable {
typealias ObserverOf = Observer<Element>
typealias KeyType = Bag<Void>.KeyType

View File

@ -16,13 +16,7 @@ public class Variable<Element>: BehaviorSubject<Element> {
super.init(value: value)
}
public func next(value: Element) {
sendNext(self, value)
public func sendNext(value: Element) {
self.on(.Next(value))
}
}
@available(*, deprecated=1.4, message="Please use variable.next, it's more clear")
public func << <E>(variable: Variable<E>, element: E) {
variable.next(element)
}

View File

@ -33,8 +33,8 @@ class Parent : NSObject {
super.init()
self.rx_observe("val", options: NSKeyValueObservingOptions.Initial.union(.New), retainSelf: false)
>- subscribeNext(callback)
>- disposeBag.addDisposable
.subscribeNext(callback)
.addDisposableTo(disposeBag)
}
deinit {
@ -48,8 +48,8 @@ class Child : NSObject {
init(parent: ParentWithChild, callback: String? -> Void) {
super.init()
parent.rx_observe("val", options: NSKeyValueObservingOptions.Initial.union(.New), retainSelf: false)
>- subscribeNext(callback)
>- disposeBag.addDisposable
.subscribeNext(callback)
.addDisposableTo(disposeBag)
}
deinit {
@ -105,7 +105,7 @@ extension KVOObservableTests {
var latest: String?
var _d: ScopedDispose? = os >- subscribeNext { latest = $0 } >- scopedDispose
var _d: ScopedDispose? = os .subscribeNext { latest = $0 } .scopedDispose
XCTAssertTrue(latest == nil)
@ -139,7 +139,7 @@ extension KVOObservableTests {
var latest: String?
var _d: ScopedDispose? = os >- subscribeNext { latest = $0 } >- scopedDispose
var _d: ScopedDispose? = os .subscribeNext { latest = $0 } .scopedDispose
XCTAssertTrue(latest == "0")
@ -173,7 +173,7 @@ extension KVOObservableTests {
var latest: String?
var _d: ScopedDispose! = os >- subscribeNext { latest = $0 } >- scopedDispose
var _d: ScopedDispose! = os .subscribeNext { latest = $0 } .scopedDispose
XCTAssertTrue(latest == "0")
@ -209,7 +209,7 @@ extension KVOObservableTests {
}
parent.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -236,7 +236,7 @@ extension KVOObservableTests {
}
parent.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -267,12 +267,12 @@ extension KVOObservableTests {
var root: HasStrongProperty! = HasStrongProperty()
root.rx_observeWeakly("property")
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest = n
}
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -297,12 +297,12 @@ extension KVOObservableTests {
var root: HasWeakProperty! = HasWeakProperty()
root.rx_observeWeakly("property")
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest = n
}
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -331,12 +331,12 @@ extension KVOObservableTests {
var root: HasWeakProperty! = HasWeakProperty()
root.rx_observeWeakly("property.property")
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest = n
}
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -380,12 +380,12 @@ extension KVOObservableTests {
XCTAssertTrue(disposed == false)
root.rx_observeWeakly("property.property")
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest = n
}
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -408,12 +408,12 @@ extension KVOObservableTests {
var root: HasStrongProperty! = HasStrongProperty()
root.rx_observeWeakly("property.property")
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest = n
}
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -457,12 +457,12 @@ extension KVOObservableTests {
XCTAssertTrue(disposed == false)
root.rx_observeWeakly("property.property")
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest = n
}
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
disposed = true
}
@ -496,7 +496,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
let observable: Observable<NSObject?> = root.rx_observeWeakly("property.property")
observable >- subscribeNext { n in
observable .subscribeNext { n in
latest?.value = n
}
@ -513,7 +513,7 @@ extension KVOObservableTests {
var gone = false
let (child, latest, dealloc) = _testObserveWeak_Strong_Weak_Observe_NilLastPropertyBecauseOfWeak()
dealloc
>- subscribeNext { n in
.subscribeNext { n in
gone = true
}
@ -538,7 +538,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
let observable: Observable<NSObject?> = root.rx_observeWeakly("property.property.property")
observable >- subscribeNext { n in
observable .subscribeNext { n in
latest?.value = n
}
@ -561,7 +561,7 @@ extension KVOObservableTests {
var gone = false
deallocatedMiddle
>- subscribeCompleted {
.subscribeCompleted {
gone = true
}
@ -580,7 +580,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
root.rx_observeWeakly("property")
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest.value = n
}
@ -589,7 +589,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -609,7 +609,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
root.rx_observeWeakly("property", options: .New)
>- subscribeNext { (n: String?) in
.subscribeNext { (n: String?) in
latest.value = n
}
@ -622,7 +622,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -642,7 +642,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
let disposable = root.rx_observe("frame")
>- subscribeNext { (n: NSRect?) in
.subscribeNext { (n: NSRect?) in
latest.value = n
}
XCTAssertTrue(latest.value == root.frame)
@ -654,7 +654,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -677,10 +677,10 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
let d = root.rx_observe("frame")
>- subscribeNext { (n: CGSize?) in
.subscribeNext { (n: CGSize?) in
latest.value = n
}
>- scopedDispose
.scopedDispose
XCTAssertTrue(latest.value == nil)
root.size = CGSizeMake(56, 1)
@ -690,7 +690,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -708,10 +708,10 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
let d = root.rx_observe("frame")
>- subscribeNext { (n: CGRect?) in
.subscribeNext { (n: CGRect?) in
latest.value = n
}
>- scopedDispose
.scopedDispose
XCTAssertTrue(latest.value == root.frame)
root.frame = CGRectMake(-2, 0, 0, 1)
@ -721,7 +721,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -739,10 +739,10 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
let d = root.rx_observe("size")
>- subscribeNext { (n: CGSize?) in
.subscribeNext { (n: CGSize?) in
latest.value = n
}
>- scopedDispose
.scopedDispose
XCTAssertTrue(latest.value == root.size)
root.size = CGSizeMake(56, 1)
@ -752,7 +752,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -770,10 +770,10 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
let d = root.rx_observe("point")
>- subscribeNext { (n: CGPoint?) in
.subscribeNext { (n: CGPoint?) in
latest.value = n
}
>- scopedDispose
.scopedDispose
XCTAssertTrue(latest.value == root.point)
@ -784,7 +784,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -803,7 +803,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
root.rx_observeWeakly("frame")
>- subscribeNext { (n: CGRect?) in
.subscribeNext { (n: CGRect?) in
latest.value = n
}
XCTAssertTrue(latest.value == root.frame)
@ -815,7 +815,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -833,7 +833,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
root.rx_observeWeakly("size")
>- subscribeNext { (n: CGSize?) in
.subscribeNext { (n: CGSize?) in
latest.value = n
}
XCTAssertTrue(latest.value == root.size)
@ -845,7 +845,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -863,7 +863,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
root.rx_observeWeakly("point")
>- subscribeNext { (n: CGPoint?) in
.subscribeNext { (n: CGPoint?) in
latest.value = n
}
@ -876,7 +876,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -894,7 +894,7 @@ extension KVOObservableTests {
XCTAssertTrue(latest.value == nil)
root.rx_observeWeakly("integer")
>- subscribeNext { (n: NSNumber?) in
.subscribeNext { (n: NSNumber?) in
latest.value = n?.integerValue
}
XCTAssertTrue(latest.value == root.integer)
@ -906,7 +906,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -921,8 +921,8 @@ extension KVOObservableTests {
var lastError: ErrorType? = nil
root.rx_observeWeakly("notExist") as Observable<NSNumber?>
>- subscribeError { error in
(root.rx_observeWeakly("notExist") as Observable<NSNumber?>)
.subscribeError { error in
lastError = error
}
@ -931,7 +931,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}
@ -945,10 +945,10 @@ extension KVOObservableTests {
var lastError: ErrorType? = nil
root.rx_observeWeakly("property.notExist") as Observable<NSNumber?>
>- subscribeError { error in
(root.rx_observeWeakly("property.notExist") as Observable<NSNumber?>)
.subscribeError { error in
lastError = error
}
}
XCTAssertTrue(lastError == nil)
@ -959,7 +959,7 @@ extension KVOObservableTests {
var rootDeallocated = false
root.rx_deallocated
>- subscribeCompleted {
.subscribeCompleted {
rootDeallocated = true
}

View File

@ -22,7 +22,7 @@ class NSNotificationCenterTests : RxTest {
XCTAssertTrue(numberOfNotifications == 0)
let subscription = notificationCenter.rx_notification("testNotification", object: nil)
>- subscribeNext { n in
.subscribeNext { n in
numberOfNotifications++
}
@ -58,7 +58,7 @@ class NSNotificationCenterTests : RxTest {
XCTAssertTrue(numberOfNotifications == 0)
let subscription = notificationCenter.rx_notification("testNotification", object: targetObject)
>- subscribeNext { n in
.subscribeNext { n in
numberOfNotifications++
}

View File

@ -23,10 +23,10 @@ extension NSObjectTests {
var fired = false
a.rx_deallocated
>- map { _ in
.map { _ in
return 1
}
>- subscribeNext { _ in
.subscribeNext { _ in
fired = true
}
@ -43,10 +43,10 @@ extension NSObjectTests {
var fired = false
a.rx_deallocated
>- map { _ in
.map { _ in
return 1
}
>- subscribeCompleted {
.subscribeCompleted {
fired = true
}
@ -63,13 +63,13 @@ extension NSObjectTests {
var fired = false
a.rx_deallocated
>- map { _ in
.map { _ in
return 1
}
>- subscribeNext { _ in
.subscribeNext { _ in
fired = true
}
>- scopedDispose
.scopedDispose
XCTAssertFalse(fired)
@ -88,10 +88,10 @@ extension NSObjectTests {
var fired = false
a.rx_deallocating
>- map { _ in
.map { _ in
return 1
}
>- subscribeNext { _ in
.subscribeNext { _ in
fired = true
}
@ -108,10 +108,10 @@ extension NSObjectTests {
var fired = false
a.rx_deallocating
>- map { _ in
.map { _ in
return 1
}
>- subscribeCompleted {
.subscribeCompleted {
fired = true
}
@ -128,13 +128,13 @@ extension NSObjectTests {
var fired = false
a.rx_deallocating
>- map { _ in
.map { _ in
return 1
}
>- subscribeNext { _ in
.subscribeNext { _ in
fired = true
}
>- scopedDispose
.scopedDispose
XCTAssertFalse(fired)

View File

@ -17,7 +17,7 @@ class UITextFieldMock {
var text: String! = "" {
didSet {
observableText.next(self.text)
observableText.sendNext(self.text)
}
}
@ -26,14 +26,17 @@ class UITextFieldMock {
}
}
extension ObservableType where E == String {
func subscribeTextOf(label: UILabelMock) -> Disposable {
return self.subscribeNext { t in
label.text = t
}
}
}
class UILabelMock {
var text: String! = ""
func rx_subscribeTextTo(source: Observable<String>) -> Disposable {
return source >- subscribeNext { t in
self.text = t
}
}
}
class UIRxTests : RxTest {
@ -44,7 +47,7 @@ class UIRxTests : RxTest {
func testReadmeExample() {
// We have some async Wolfram Alpha API that calculates is number prime.
let WolframAlphaIsPrime: (Int) -> Observable<PrimeNumber> = { returnElement(PrimeNumber($0, isPrime($0))) }
let WolframAlphaIsPrime: (Int) -> Observable<PrimeNumber> = { just(PrimeNumber($0, isPrime($0))) }
let text = Variable<String>("")
let resultText = ""
@ -54,11 +57,11 @@ class UIRxTests : RxTest {
let resultLabel = UILabelMock()
let disposable = primeTextField.rx_text()
>- map { WolframAlphaIsPrime(Int($0) ?? 0) }
>- concat
>- map { "number \($0.n) is prime? \($0.isPrime)" }
>- resultLabel.rx_subscribeTextTo
>- scopedDispose
.map { WolframAlphaIsPrime(Int($0) ?? 0) }
.concat
.map { "number \($0.n) is prime? \($0.isPrime)" }
.subscribeTextOf(resultLabel)
.scopedDispose
// this will set resultLabel.text! == "number 43 is prime? true"
primeTextField.text = "43"

View File

@ -15,18 +15,18 @@ class UIControlRxTests : RxTest {
func testSubscribeEnabledToTrue() {
let subject = UIControl()
let enabledSequence = Variable<Bool>(false)
let disposable = enabledSequence >- subject.rx_subscribeEnabledTo
let disposable = enabledSequence.subscribeEnabledOf(subject)
enabledSequence.next(true)
enabledSequence.sendNext(true)
XCTAssert(subject.enabled == true, "Expected enabled set to true")
}
func testSubscribeEnabledToFalse() {
let subject = UIControl()
let enabledSequence = Variable<Bool>(true)
let disposable = enabledSequence >- subject.rx_subscribeEnabledTo
let disposable = enabledSequence.subscribeEnabledOf(subject)
enabledSequence.next(false)
enabledSequence.sendNext(false)
XCTAssert(subject.enabled == false, "Expected enabled set to false")
}
}

View File

@ -13,7 +13,7 @@ class ConnectableObservable<Element> : ConnectableObservableType<Element> {
let _o: ConnectableObservableType<Element>
init(o: Observable<Element>, s: SubjectType<Element, Element>) {
_o = o >- multicast(s)
_o = o .multicast(s)
super.init()
}

View File

@ -24,7 +24,7 @@ extension AnonymousObservableTests {
var elements = [Int]()
let d = a >- subscribeNext { n in
let d = a .subscribeNext { n in
elements.append(n)
}
@ -48,7 +48,7 @@ extension AnonymousObservableTests {
var elements = [Int]()
let d = a >- subscribeNext { n in
let d = a .subscribeNext { n in
elements.append(n)
}
@ -72,7 +72,7 @@ extension AnonymousObservableTests {
var elements = [Int]()
let d = a >- subscribeNext { n in
let d = a .subscribeNext { n in
elements.append(n)
}

View File

@ -66,12 +66,12 @@ class AssumptionsTest : RxTest {
func testFunctionReturnValueOverload() {
returnSomething()
>- subscribeNext { (n: AnyObject?) in
.subscribeNext { (n: AnyObject?) in
XCTAssertEqual("\(n ?? NSNull())", "a")
}
returnSomething()
>- subscribeNext { (n: CGRect?) in
.subscribeNext { (n: CGRect?) in
XCTAssertEqual(n!, CGRectMake(0, 0, 100, 100))
}
}

View File

@ -151,10 +151,10 @@ class DelegateProxyTest : RxTest {
var observedFeedRequest = false
let d = view.rx_proxy.observe("threeDView:didLearnSomething:")
>- subscribeNext { n in
.subscribeNext { n in
observedFeedRequest = true
}
>- scopedDispose
.scopedDispose
XCTAssertTrue(!observedFeedRequest)
view.delegate?.threeDView?(view, didLearnSomething: "Psssst ...")
@ -172,16 +172,16 @@ class DelegateProxyTest : RxTest {
var nMessages = 0
var d = view.rx_proxy.observe("threeDView:didLearnSomething:")
>- subscribeNext { n in
.subscribeNext { n in
nMessages++
}
>- scopedDispose
.scopedDispose
XCTAssertTrue(nMessages == 0)
view.delegate?.threeDView?(view, didLearnSomething: "Psssst ...")
XCTAssertTrue(nMessages == 1)
d = scopedDispose(NopDisposable.instance)
d = NopDisposable.instance.scopedDispose
view.delegate?.threeDView?(view, didLearnSomething: "Psssst ...")
XCTAssertTrue(nMessages == 1)
@ -211,11 +211,11 @@ class DelegateProxyTest : RxTest {
var receivedArgument: NSIndexPath? = nil
let d = view.rx_proxy.observe("threeDView:didGetXXX:")
>- subscribeNext { n in
.subscribeNext { n in
let ip = n[1] as! NSIndexPath
receivedArgument = ip
}
>- scopedDispose
.scopedDispose
XCTAssertTrue(receivedArgument === nil)
view.delegate?.threeDView?(view, didGetXXX: sentArgument)
@ -240,7 +240,7 @@ class DelegateProxyTest : RxTest {
var receivedArgument: NSIndexPath? = nil
view.rx_proxy.observe("threeDView:didGetXXX:")
>- subscribeCompleted {
.subscribeCompleted {
completed.value = true
}

View File

@ -30,7 +30,7 @@ extension ObservableAggregateTest {
])
let res = scheduler.start { xs >- aggregate(42, +) }
let res = scheduler.start { xs.aggregate(42, +) }
let correctMessages = [
next(250, 42),
@ -54,7 +54,7 @@ extension ObservableAggregateTest {
completed(250)
])
let res = scheduler.start { xs >- aggregate(42, +) }
let res = scheduler.start { xs.aggregate(42, +) }
let correctMessages = [
next(250, 42 + 24),
@ -77,7 +77,7 @@ extension ObservableAggregateTest {
error(210, testError),
])
let res = scheduler.start { xs >- aggregate(42, +) }
let res = scheduler.start { xs.aggregate(42, +) }
let correctMessages: [Recorded<Int>] = [
error(210, testError)
@ -98,7 +98,7 @@ extension ObservableAggregateTest {
next(150, 1),
])
let res = scheduler.start { xs >- aggregate(42, +) }
let res = scheduler.start { xs.aggregate(42, +) }
let correctMessages: [Recorded<Int>] = [
]
@ -124,7 +124,7 @@ extension ObservableAggregateTest {
completed(260)
])
let res = scheduler.start { xs >- aggregate(42, +) }
let res = scheduler.start { xs.aggregate(42, +) }
let correctMessages: [Recorded<Int>] = [
next(260, 42 + 0 + 1 + 2 + 3 + 4),
@ -152,7 +152,7 @@ extension ObservableAggregateTest {
completed(260)
])
let res = scheduler.start { xs >- aggregateOrDie(42, { $1 < 3 ? success($0 + $1) : failure(testError)}) }
let res = scheduler.start { xs.aggregateOrDie(42, { $1 < 3 ? success($0 + $1) : failure(testError)}) }
let correctMessages: [Recorded<Int>] = [
error(240, testError)
@ -174,7 +174,7 @@ extension ObservableAggregateTest {
completed(250)
])
let res = scheduler.start { xs >- aggregate(42, +, { $0 * 5 }) }
let res = scheduler.start { xs.aggregate(42, +, { $0 * 5 }) }
let correctMessages = [
next(250, 42 * 5),
@ -198,7 +198,7 @@ extension ObservableAggregateTest {
completed(250)
])
let res = scheduler.start { xs >- aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let res = scheduler.start { xs.aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let correctMessages = [
next(250, (42 + 24) * 5),
@ -221,7 +221,7 @@ extension ObservableAggregateTest {
error(210, testError),
])
let res = scheduler.start { xs >- aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let res = scheduler.start { xs.aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let correctMessages: [Recorded<Int>] = [
error(210, testError)
@ -242,7 +242,7 @@ extension ObservableAggregateTest {
next(150, 1),
])
let res = scheduler.start { xs >- aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let res = scheduler.start { xs.aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let correctMessages: [Recorded<Int>] = [
]
@ -268,7 +268,7 @@ extension ObservableAggregateTest {
completed(260)
])
let res = scheduler.start { xs >- aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let res = scheduler.start { xs.aggregate(42, { $0 + $1 }, { $0 * 5 }) }
let correctMessages: [Recorded<Int>] = [
next(260, (42 + 0 + 1 + 2 + 3 + 4) * 5),
@ -296,7 +296,7 @@ extension ObservableAggregateTest {
completed(260)
])
let res = scheduler.start { xs >- aggregateOrDie(42, { $1 < 3 ? success($0 + $1) : failure(testError) }, { success($0 * 5) }) }
let res = scheduler.start { xs.aggregateOrDie(42, { $1 < 3 ? success($0 + $1) : failure(testError) }, { success($0 * 5) }) }
let correctMessages: [Recorded<Int>] = [
error(240, testError)
@ -323,7 +323,7 @@ extension ObservableAggregateTest {
completed(260)
])
let res = scheduler.start { xs >- aggregateOrDie(42, { success($0 + $1) }, { (_: Int) -> RxResult<Int> in failure(testError) }) }
let res = scheduler.start { xs.aggregateOrDie(42, { success($0 + $1) }, { (_: Int) -> RxResult<Int> in failure(testError) }) }
let correctMessages: [Recorded<Int>] = [
error(260, testError)

View File

@ -21,10 +21,10 @@ extension ObservableBindingTest {
var nEvents = 0
let observable = ConnectableObservable(o: returnElements(0, 1, 2), s: subject)
let _d = observable >- subscribeNext { n in
let observable = ConnectableObservable(o: sequence(0, 1, 2), s: subject)
let _d = observable .subscribeNext { n in
nEvents++
} >- scopedDispose
} .scopedDispose
observable.connect().dispose()
@ -36,10 +36,10 @@ extension ObservableBindingTest {
var nEvents = 0
let observable = ConnectableObservable(o: concat([returnElements(0, 1, 2), failWith(testError)]), s: subject)
let _d = observable >- subscribeError { n in
let observable = ConnectableObservable(o: concat([sequence(0, 1, 2), failWith(testError)]), s: subject)
let _d = observable .subscribeError { n in
nEvents++
} >- scopedDispose
} .scopedDispose
observable.connect().dispose()
@ -52,9 +52,9 @@ extension ObservableBindingTest {
var nEvents = 0
let observable = ConnectableObservable(o: failWith(testError), s: subject)
let _d = observable >- subscribeError { n in
let _d = observable .subscribeError { n in
nEvents++
} >- scopedDispose
} .scopedDispose
observable.connect().dispose()
@ -67,9 +67,9 @@ extension ObservableBindingTest {
var nEvents = 0
let observable = ConnectableObservable(o: empty(), s: subject)
let d = observable >- subscribeCompleted {
let d = observable .subscribeCompleted {
nEvents++
} >- scopedDispose
} .scopedDispose
observable.connect().dispose()
@ -91,7 +91,7 @@ extension ObservableBindingTest {
let conn = ConnectableObservable(o: xs, s: subject)
let res = scheduler.start { conn >- refCount }
let res = scheduler.start { conn .refCount }
XCTAssertEqual(res.messages, [
next(210, 1),
@ -122,7 +122,7 @@ extension ObservableBindingTest {
let subject = MySubject<Int>()
let conn = ConnectableObservable(o: xs, s: subject)
let refd = conn >- refCount
let refd = conn .refCount
let dis1 = refd.subscribe(NopObserver())
XCTAssertEqual(1, count)
@ -152,8 +152,8 @@ extension ObservableBindingTest {
func testRefCount_Error() {
let xs: Observable<Int> = failWith(testError)
let res = xs >- publish >- refCount
res >- subscribe { event in
let res = xs.publish .refCount
res .subscribe { event in
switch event {
case .Next:
XCTAssertTrue(false)
@ -163,7 +163,7 @@ extension ObservableBindingTest {
XCTAssertTrue(false)
}
}
res >- subscribe { event in
res .subscribe { event in
switch event {
case .Next:
XCTAssertTrue(false)
@ -191,7 +191,7 @@ extension ObservableBindingTest {
completed(300)
])
let res = xs >- publish >- refCount
let res = xs.publish .refCount
var d1: Disposable!
let o1: MockObserver<Int> = scheduler.createObserver()
@ -249,10 +249,10 @@ extension ObservableBindingTest {
func testReplay_DeadlockSimple() {
var nEvents = 0
let observable = returnElements(0, 1, 2) >- replay(3) >- refCount
_ = observable >- subscribeNext { n in
let observable = sequence(0, 1, 2).replay(3).refCount
_ = observable .subscribeNext { n in
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 3)
}
@ -260,10 +260,10 @@ extension ObservableBindingTest {
func testReplay_DeadlockErrorAfterN() {
var nEvents = 0
let observable = concat([returnElements(0, 1, 2), failWith(testError)]) >- replay(3) >- refCount
_ = observable >- subscribeError { n in
let observable = concat([sequence(0, 1, 2), failWith(testError)]).replay(3).refCount
_ = observable .subscribeError { n in
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 1)
}
@ -271,10 +271,10 @@ extension ObservableBindingTest {
func testReplay_DeadlockErrorImmediatelly() {
var nEvents = 0
let observable: Observable<Int> = failWith(testError) >- replay(3) >- refCount
_ = observable >- subscribeError { n in
let observable: Observable<Int> = failWith(testError).replay(3).refCount
_ = observable .subscribeError { n in
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 1)
}
@ -282,10 +282,10 @@ extension ObservableBindingTest {
func testReplay_DeadlockEmpty() {
var nEvents = 0
let observable: Observable<Int> = empty() >- replay(3) >- refCount
_ = observable >- subscribeCompleted {
let observable: Observable<Int> = empty().replay(3).refCount
_ = observable .subscribeCompleted {
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 1)
}
@ -293,10 +293,10 @@ extension ObservableBindingTest {
func testReplay1_DeadlockSimple() {
var nEvents = 0
let observable = returnElements(0, 1, 2) >- replay(1) >- refCount
_ = observable >- subscribeNext { n in
let observable = sequence(0, 1, 2).replay(1).refCount
_ = observable .subscribeNext { n in
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 3)
}
@ -304,10 +304,10 @@ extension ObservableBindingTest {
func testReplay1_DeadlockErrorAfterN() {
var nEvents = 0
let observable = concat([returnElement(0, 1, 2), failWith(testError)]) >- replay(1) >- refCount
_ = observable >- subscribeError { n in
let observable = concat([just(0, 1, 2), failWith(testError)]).replay(1).refCount
_ = observable .subscribeError { n in
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 1)
}
@ -315,10 +315,10 @@ extension ObservableBindingTest {
func testReplay1_DeadlockErrorImmediatelly() {
var nEvents = 0
let observable: Observable<Int> = failWith(testError) >- replay(1) >- refCount
_ = observable >- subscribeError { n in
let observable: Observable<Int> = failWith(testError).replay(1).refCount
_ = observable .subscribeError { n in
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 1)
}
@ -326,10 +326,10 @@ extension ObservableBindingTest {
func testReplay1_DeadlockEmpty() {
var nEvents = 0
let observable: Observable<Int> = empty() >- replay(1) >- refCount
_ = observable >- subscribeCompleted {
let observable: Observable<Int> = empty().replay(1).refCount
_ = observable .subscribeCompleted {
nEvents++
} >- scopedDispose
} .scopedDispose
XCTAssertEqual(nEvents, 1)
}
@ -359,7 +359,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(3) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(Defaults.disposed) { subscription.dispose() }
@ -413,7 +413,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(3) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(Defaults.disposed) { subscription.dispose() }
@ -465,7 +465,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(3) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(Defaults.disposed) { subscription.dispose() }
@ -517,7 +517,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(3) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(475) { subscription.dispose() }
@ -570,7 +570,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(1) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(Defaults.disposed) { subscription.dispose() }
@ -622,7 +622,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(1) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(Defaults.disposed) { subscription.dispose() }
@ -672,7 +672,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(1) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(Defaults.disposed) { subscription.dispose() }
@ -722,7 +722,7 @@ extension ObservableBindingTest {
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
scheduler.scheduleAt(Defaults.created) { ys = xs >- replay(1) }
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
scheduler.scheduleAt(475) { subscription.dispose() }

View File

@ -22,27 +22,27 @@ class ObservableBlockingTest : RxTest {
extension ObservableBlockingTest {
func testToArray_empty() {
XCTAssert((empty() as Observable<Int> >- toArray).get() == [])
XCTAssert(((empty() as Observable<Int>).toArray()).get() == [])
}
func testToArray_return() {
XCTAssert((just(42) >- toArray).get() == [42])
XCTAssert((just(42).toArray()).get() == [42])
}
func testToArray_fail() {
XCTAssert((failWith(testError) as Observable<Int> >- toArray).isFailure)
XCTAssert(((failWith(testError) as Observable<Int>).toArray()).isFailure)
}
func testToArray_someData() {
XCTAssert((returnElements(42, 43, 44, 45) >- toArray).get() == [42, 43, 44, 45])
XCTAssert((sequence(42, 43, 44, 45).toArray()).get() == [42, 43, 44, 45])
}
func testToArray_withRealScheduler() {
let scheduler = ConcurrentDispatchQueueScheduler(globalConcurrentQueuePriority: .Default)
let array = interval(0.001, scheduler)
>- take(10)
>- toArray
.take(10)
.toArray()
XCTAssert(array.get() == Array(0..<10))
}
@ -52,27 +52,27 @@ extension ObservableBlockingTest {
extension ObservableBlockingTest {
func testFirst_empty() {
XCTAssert((empty() as Observable<Int> >- first).get() == nil)
XCTAssert(((empty() as Observable<Int>).first).get() == nil)
}
func testFirst_return() {
XCTAssert((just(42) >- first).get() == 42)
XCTAssert((just(42).first).get() == 42)
}
func testFirst_fail() {
XCTAssert((failWith(testError) as Observable<Int> >- first).isFailure)
XCTAssert(((failWith(testError) as Observable<Int>).first).isFailure)
}
func testFirst_someData() {
XCTAssert((returnElements(42, 43, 44, 45) >- first).get() == 42)
XCTAssert((sequence(42, 43, 44, 45).first).get() == 42)
}
func testFirst_withRealScheduler() {
let scheduler = ConcurrentDispatchQueueScheduler(globalConcurrentQueuePriority: .Default)
let array = interval(0.001, scheduler)
>- take(10)
>- first
.take(10)
.first
XCTAssert(array.get() == 0)
}
@ -82,27 +82,27 @@ extension ObservableBlockingTest {
extension ObservableBlockingTest {
func testLast_empty() {
XCTAssert((empty() as Observable<Int> >- last).get() == nil)
XCTAssert(((empty() as Observable<Int>).last).get() == nil)
}
func testLast_return() {
XCTAssert((just(42) >- last).get() == 42)
XCTAssert((just(42).last).get() == 42)
}
func testLast_fail() {
XCTAssert((failWith(testError) as Observable<Int> >- last).isFailure)
XCTAssert(((failWith(testError) as Observable<Int>).last).isFailure)
}
func testLast_someData() {
XCTAssert((returnElements(42, 43, 44, 45) >- last).get() == 45)
XCTAssert((sequence(42, 43, 44, 45).last).get() == 45)
}
func testLast_withRealScheduler() {
let scheduler = ConcurrentDispatchQueueScheduler(globalConcurrentQueuePriority: .Default)
let array = interval(0.001, scheduler)
>- take(10)
>- last
.take(10)
.last
XCTAssert(array.get() == 9)
}

View File

@ -38,10 +38,11 @@ extension ObservableConcurrencyTest {
var nEvents = 0
let observable = returnElement(0) >- observeSingleOn(scheduler)
let _d = observable >- subscribeNext { n in
nEvents++
} >- scopedDispose
let observable = just(0).observeSingleOn(scheduler)
let _d = observable .subscribeNext { n in
nEvents++
}
.scopedDispose
scheduler.start()
@ -53,10 +54,11 @@ extension ObservableConcurrencyTest {
var nEvents = 0
let observable: Observable<Int> = failWith(testError) >- observeSingleOn(scheduler)
let _d = observable >- subscribeError { n in
nEvents++
} >- scopedDispose
let observable: Observable<Int> = failWith(testError).observeSingleOn(scheduler)
let _d = observable.subscribeError { n in
nEvents++
}
.scopedDispose
scheduler.start()
@ -68,10 +70,11 @@ extension ObservableConcurrencyTest {
var nEvents = 0
let observable: Observable<Int> = empty() >- observeSingleOn(scheduler)
let _d = observable >- subscribeCompleted {
nEvents++
} >- scopedDispose
let observable: Observable<Int> = empty().observeSingleOn(scheduler)
let _d = observable .subscribeCompleted {
nEvents++
}
.scopedDispose
scheduler.start()
@ -82,10 +85,10 @@ extension ObservableConcurrencyTest {
let scheduler = TestScheduler(initialClock: 0)
let xs = scheduler.createHotObservable([
next(150, 1),
next(150, 1),
])
let res = scheduler.start { xs >- observeSingleOn(scheduler) }
let res = scheduler.start { xs.observeSingleOn(scheduler) }
let correctMessages: [Recorded<Int>] = [
]
@ -106,7 +109,7 @@ extension ObservableConcurrencyTest {
completed(300)
])
let res = scheduler.start { xs >- observeSingleOn(scheduler) }
let res = scheduler.start { xs.observeSingleOn(scheduler) }
let correctMessages: [Recorded<Int>] = [
completed(301)
@ -129,7 +132,7 @@ extension ObservableConcurrencyTest {
completed(300)
])
let res = scheduler.start { xs >- observeSingleOn(scheduler) }
let res = scheduler.start { xs.observeSingleOn(scheduler) }
let correctMessages: [Recorded<Int>] = [
next(301, 0),
@ -152,7 +155,7 @@ extension ObservableConcurrencyTest {
error(300, testError)
])
let res = scheduler.start { xs >- observeSingleOn(scheduler) }
let res = scheduler.start { xs.observeSingleOn(scheduler) }
let correctMessages: [Recorded<Int>] = [
error(301, testError)
@ -175,7 +178,7 @@ extension ObservableConcurrencyTest {
error(300, testError)
])
let res = scheduler.start(290) { xs >- observeSingleOn(scheduler) }
let res = scheduler.start(290) { xs.observeSingleOn(scheduler) }
let correctMessages: [Recorded<Int>] = [
]
@ -194,7 +197,7 @@ extension ObservableConcurrencyTest {
func runDispatchQueueSchedulerTests(tests: (scheduler: SerialDispatchQueueScheduler) -> Disposable) {
let scheduler = SerialDispatchQueueScheduler(internalSerialQueueName: "testQueue1")
let _ = runDispatchQueueSchedulerTests(scheduler, tests: tests) >- scopedDispose
let _ = runDispatchQueueSchedulerTests(scheduler, tests: tests).scopedDispose
}
func runDispatchQueueSchedulerTests(scheduler: SerialDispatchQueueScheduler, tests: (scheduler: SerialDispatchQueueScheduler) -> Disposable) -> Disposable {
@ -234,8 +237,9 @@ extension ObservableConcurrencyTest {
var didExecute = false
runDispatchQueueSchedulerTests { scheduler in
let observable = returnElement(0) >- observeOn(scheduler)
return observable >- subscribeNext { n in
let observable = just(0)
.observeOn(scheduler)
return observable .subscribeNext { n in
didExecute = true
XCTAssert(NSThread.currentThread() !== unitTestsThread)
}
@ -250,7 +254,8 @@ extension ObservableConcurrencyTest {
func testObserveOnDispatchQueue_EnsureCorrectImplementationIsChosen() {
runDispatchQueueSchedulerTests { scheduler in
XCTAssert(numberOfSerialDispatchQueueObservables == 0)
let observable = returnElement(0) >- observeOn(scheduler)
let observable = just(0)
.observeOn(scheduler)
XCTAssert(numberOfSerialDispatchQueueObservables == 1)
return NopDisposable.instance
}
@ -263,9 +268,9 @@ extension ObservableConcurrencyTest {
var numberOfExecutions = 0
runDispatchQueueSchedulerTests { scheduler in
XCTAssert(numberOfSerialDispatchQueueObservables == 0)
return returnElements(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>- observeOn(scheduler)
>- subscribeNext { e in
return sequence(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.observeOn(scheduler)
.subscribeNext { e in
XCTAssert(OSAtomicIncrement32(&numberOfConcurrentEvents) == 1)
self.sleep(0.1) // should be enough to block the queue, so if it's concurrent, it will fail
XCTAssert(OSAtomicDecrement32(&numberOfConcurrentEvents) == 0)
@ -282,8 +287,8 @@ extension ObservableConcurrencyTest {
var nEvents = 0
runDispatchQueueSchedulerTests { scheduler in
let observable: Observable<Int> = failWith(testError) >- observeOn(scheduler)
return observable >- subscribeError { n in
let observable: Observable<Int> = failWith(testError).observeOn(scheduler)
return observable .subscribeError { n in
nEvents++
}
}
@ -295,8 +300,8 @@ extension ObservableConcurrencyTest {
var nEvents = 0
runDispatchQueueSchedulerTests { scheduler in
let observable: Observable<Int> = empty() >- observeOn(scheduler)
return observable >- subscribeCompleted {
let observable: Observable<Int> = empty().observeOn(scheduler)
return observable .subscribeCompleted {
nEvents++
}
}
@ -308,8 +313,8 @@ extension ObservableConcurrencyTest {
runDispatchQueueSchedulerTests { scheduler in
let xs: Observable<Int> = never()
return xs
>- observeOn(scheduler)
>- subscribeNext { n in
.observeOn(scheduler)
.subscribeNext { n in
XCTAssert(false)
}
}
@ -321,7 +326,7 @@ extension ObservableConcurrencyTest {
runDispatchQueueSchedulerMultiplexedTests([
{ scheduler in
let subscription = (xs >- observeOn(scheduler)).subscribe(observer)
let subscription = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendNext(xs, 0)
@ -364,7 +369,7 @@ extension ObservableConcurrencyTest {
runDispatchQueueSchedulerMultiplexedTests([
{ scheduler in
let subscription = (xs >- observeOn(scheduler)).subscribe(observer)
let subscription = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendCompleted(xs)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
@ -387,7 +392,7 @@ extension ObservableConcurrencyTest {
runDispatchQueueSchedulerMultiplexedTests([
{ scheduler in
let subscription = (xs >- observeOn(scheduler)).subscribe(observer)
let subscription = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendNext(xs, 0)
@ -431,7 +436,7 @@ extension ObservableConcurrencyTest {
runDispatchQueueSchedulerMultiplexedTests([
{ scheduler in
subscription = (xs >- observeOn(scheduler)).subscribe(observer)
subscription = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendNext(xs, 0)
@ -475,7 +480,7 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
let scheduler = self.createScheduler()
XCTAssert(numberOfSerialDispatchQueueObservables == 0)
let observable = returnElement(0) >- observeOn(scheduler)
let observable = just(0).observeOn(scheduler)
self.sleep(0.1)
XCTAssert(numberOfSerialDispatchQueueObservables == 0)
}
@ -529,8 +534,7 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
_ = scheduler.schedule((), action: concurrent)
stop >-
last
let _ = stop.last
XCTAssertEqual(events, ["Started", "Started", "Ended", "Ended"])
}
@ -540,8 +544,8 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
let xs: Observable<Int> = never()
let subscription = xs
>- observeOn(scheduler)
>- subscribeNext { n in
.observeOn(scheduler)
.subscribeNext { n in
XCTAssert(false)
}
@ -558,7 +562,7 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
let stop = Variable(0)
let subscription = (xs >- observeOn(scheduler)).subscribe(observer)
let subscription = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendNext(xs, 0)
@ -601,7 +605,7 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
let scheduler = createScheduler()
_ = (xs >- observeOn(scheduler)).subscribe(observer)
_ = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendCompleted(xs)
@ -622,8 +626,8 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
let scheduler = createScheduler()
let res = xs
>- observeOn(scheduler)
>- map { v -> Int in
.observeOn(scheduler)
.map { v -> Int in
if v == 0 {
self.sleep(0.1) // 100 ms is enough
executed = true
@ -657,7 +661,7 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
let scheduler = createScheduler()
let _ = (xs >- observeOn(scheduler)).subscribe(observer)
let _ = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendNext(xs, 0)
@ -696,7 +700,7 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
let observer = PrimitiveMockObserver<Int>()
let scheduler = createScheduler()
let subscription = (xs >- observeOn(scheduler)).subscribe(observer)
let subscription = (xs.observeOn(scheduler)).subscribe(observer)
XCTAssert(xs.subscriptions == [SubscribedToHotObservable])
sendNext(xs, 0)
@ -744,7 +748,7 @@ extension ObservableConcurrencyTest {
}
let res = scheduler.start {
xs >- subscribeOn(scheduler)
xs.subscribeOn(scheduler)
}
XCTAssertEqual(res.messages, [
@ -763,7 +767,7 @@ extension ObservableConcurrencyTest {
])
let res = scheduler.start {
xs >- subscribeOn(scheduler)
xs.subscribeOn(scheduler)
}
XCTAssertEqual(res.messages, [
@ -783,7 +787,7 @@ extension ObservableConcurrencyTest {
])
let res = scheduler.start {
xs >- subscribeOn(scheduler)
xs.subscribeOn(scheduler)
}
XCTAssertEqual(res.messages, [
@ -804,7 +808,7 @@ extension ObservableConcurrencyTest {
])
let res = scheduler.start {
xs >- subscribeOn(scheduler)
xs.subscribeOn(scheduler)
}
XCTAssertEqual(res.messages, [

View File

@ -20,12 +20,12 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule2() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
var result: Int! = nil
let _ = zip(v0, v1) { (a0, a1) in a0 + a1 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1) { (a0, a1) in a0 + a1 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 3)
}
@ -171,13 +171,13 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule3() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
var result: Int! = nil
let _ = zip(v0, v1, v2) { (a0, a1, a2) in a0 + a1 + a2 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2) { (a0, a1, a2) in a0 + a1 + a2 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 6)
}
@ -350,14 +350,14 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule4() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v3: Observable<Int> = returnElement(4)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
let v3: Observable<Int> = just(4)
var result: Int! = nil
let _ = zip(v0, v1, v2, v3) { (a0, a1, a2, a3) in a0 + a1 + a2 + a3 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2, v3) { (a0, a1, a2, a3) in a0 + a1 + a2 + a3 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 10)
}
@ -558,15 +558,15 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule5() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v3: Observable<Int> = returnElement(4)
let v4: Observable<Int> = returnElement(5)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
let v3: Observable<Int> = just(4)
let v4: Observable<Int> = just(5)
var result: Int! = nil
let _ = zip(v0, v1, v2, v3, v4) { (a0, a1, a2, a3, a4) in a0 + a1 + a2 + a3 + a4 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2, v3, v4) { (a0, a1, a2, a3, a4) in a0 + a1 + a2 + a3 + a4 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 15)
}
@ -796,16 +796,16 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule6() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v3: Observable<Int> = returnElement(4)
let v4: Observable<Int> = returnElement(5)
let v5: Observable<Int> = returnElement(6)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
let v3: Observable<Int> = just(4)
let v4: Observable<Int> = just(5)
let v5: Observable<Int> = just(6)
var result: Int! = nil
let _ = zip(v0, v1, v2, v3, v4, v5) { (a0, a1, a2, a3, a4, a5) in a0 + a1 + a2 + a3 + a4 + a5 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2, v3, v4, v5) { (a0, a1, a2, a3, a4, a5) in a0 + a1 + a2 + a3 + a4 + a5 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 21)
}
@ -1065,17 +1065,17 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule7() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v3: Observable<Int> = returnElement(4)
let v4: Observable<Int> = returnElement(5)
let v5: Observable<Int> = returnElement(6)
let v6: Observable<Int> = returnElement(7)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
let v3: Observable<Int> = just(4)
let v4: Observable<Int> = just(5)
let v5: Observable<Int> = just(6)
let v6: Observable<Int> = just(7)
var result: Int! = nil
let _ = zip(v0, v1, v2, v3, v4, v5, v6) { (a0, a1, a2, a3, a4, a5, a6) in a0 + a1 + a2 + a3 + a4 + a5 + a6 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2, v3, v4, v5, v6) { (a0, a1, a2, a3, a4, a5, a6) in a0 + a1 + a2 + a3 + a4 + a5 + a6 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 28)
}
@ -1366,18 +1366,18 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule8() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v3: Observable<Int> = returnElement(4)
let v4: Observable<Int> = returnElement(5)
let v5: Observable<Int> = returnElement(6)
let v6: Observable<Int> = returnElement(7)
let v7: Observable<Int> = returnElement(8)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
let v3: Observable<Int> = just(4)
let v4: Observable<Int> = just(5)
let v5: Observable<Int> = just(6)
let v6: Observable<Int> = just(7)
let v7: Observable<Int> = just(8)
var result: Int! = nil
let _ = zip(v0, v1, v2, v3, v4, v5, v6, v7) { (a0, a1, a2, a3, a4, a5, a6, a7) in a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2, v3, v4, v5, v6, v7) { (a0, a1, a2, a3, a4, a5, a6, a7) in a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 36)
}
@ -1700,19 +1700,19 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule9() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v3: Observable<Int> = returnElement(4)
let v4: Observable<Int> = returnElement(5)
let v5: Observable<Int> = returnElement(6)
let v6: Observable<Int> = returnElement(7)
let v7: Observable<Int> = returnElement(8)
let v8: Observable<Int> = returnElement(9)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
let v3: Observable<Int> = just(4)
let v4: Observable<Int> = just(5)
let v5: Observable<Int> = just(6)
let v6: Observable<Int> = just(7)
let v7: Observable<Int> = just(8)
let v8: Observable<Int> = just(9)
var result: Int! = nil
let _ = zip(v0, v1, v2, v3, v4, v5, v6, v7, v8) { (a0, a1, a2, a3, a4, a5, a6, a7, a8) in a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2, v3, v4, v5, v6, v7, v8) { (a0, a1, a2, a3, a4, a5, a6, a7, a8) in a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 45)
}
@ -2068,20 +2068,20 @@ extension ObservableMultipleTest {
func testZip_ImmediateSchedule10() {
let v0: Observable<Int> = returnElement(1)
let v1: Observable<Int> = returnElement(2)
let v2: Observable<Int> = returnElement(3)
let v3: Observable<Int> = returnElement(4)
let v4: Observable<Int> = returnElement(5)
let v5: Observable<Int> = returnElement(6)
let v6: Observable<Int> = returnElement(7)
let v7: Observable<Int> = returnElement(8)
let v8: Observable<Int> = returnElement(9)
let v9: Observable<Int> = returnElement(10)
let v0: Observable<Int> = just(1)
let v1: Observable<Int> = just(2)
let v2: Observable<Int> = just(3)
let v3: Observable<Int> = just(4)
let v4: Observable<Int> = just(5)
let v5: Observable<Int> = just(6)
let v6: Observable<Int> = just(7)
let v7: Observable<Int> = just(8)
let v8: Observable<Int> = just(9)
let v9: Observable<Int> = just(10)
var result: Int! = nil
let _ = zip(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) { (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) in a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 } >- subscribeNext { result = $0 }
let _ = zip(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) { (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) in a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 } .subscribeNext { (next: Int) -> Void in result = next }
XCTAssertEqual(result, 55)
}

Some files were not shown because too many files have changed in this diff Show More