RxSwift Cheatsheet

RxSwift - Provides a reactive and functional way of subscribing, reacting to and propagating changes through a system.

Everything in RxSwift is an Observable Sequence (something that operates on OR subscribes to events by an another observable sequence).

let hello = Observable.just("Hello Rx")
let fib = Observable.from([0,1,2,3,4,5,6])
let dictSeq = Observable.from([1: "Hello", 2:"World"])

Subscribing to Events

let hello = Observable.of("Hello Rx")
let subscription = helloSequence.subscribe { event in
	print(event)
}

OUTPUTS:
next("Hello rx")

Events in RxSwift

enum Event { 
	case next
	case error
	case completed
}

Using Event

let hello = Observable.from([H, e, l, l, o])
let subscription = hello.subscribe { event in
	switch event {
		case .next(let value):
			print(value)
		case .error(let error):
			print(error)
		case .completed:
			print("completed")
	}
}

## Dispose

// Creating a DisposeBag so subscribtion will be cancelled correctly
let bag = DisposeBag()
// Creating an Observable Sequence that emits a String value
let observable = Observable.just("Hello Rx!")
// Creating a subscription just for next events
let subscription = observable.subscribe (onNext:{ 
    print($0)
})
// Adding the Subscription to a Dispose Bag
subscription.addDisposableTo(bag)

Subjects

A form of observable sequence

  1. PublishSubject
  2. BehaviourSubject
  3. ReplaySubject
  4. Variable

Number of events on subscription:

  1. Publish: 0
  2. Behaviour & Variable: 1
  3. Replay: N

Transformations

### Map

Observable<Int>.of(1, 2, 3, 4).map { value in
	return value * 10
}.subscribe(onNext: {
	print($0)
})

FlatMap

let seq1 = Observable<Int>.of(1,2)
let seq2 = Observable<Int>.of(1,2)

let seqOfSeqs = Observable.of(seq1, seq2)

seqOfSeqs.flatMap { return $0 }.subscribe(onNext: {
	print($0)
})

OUTPUT: 1 2 1 2

### Scan Like reduce, aggregates values

Observable.of(1,2,3,4,5).scan(0) { seed, value in
	return seed + value
}.subscribe(onNext: {
	print($0)
})

Output 1,3,6,10,15

Buffer

The Buffer operator transforms an Observable that emits items into an Observable that emits buffered collections of those items.

SequenceThatEmitsWithDifferentIntervals
      .buffer(timeSpan: 150, count: 3, scheduler:s)
      .subscribe(onNext:{
    print($0)
})
OUTPUT: [1] [2,3] [4] [5,6] [7] [] 

Filter

The Basic filter Operation works similar to the swift equivalent. You just define a condition that needs to be passed and if the condition is fulfilled a .next event will be emitted to its subscribers.

Observable.of(2,30,22,5,60,1).filter{$0 > 10}.subscribe(onNext:{
      print($0)
})

OUTPUT: 30 22 60

Distinct until changed

If you just want to emit next Events if the value changed from previous ones you need to use distinctUntilChanged.

Observable.of(1,2,2,1,3).distinctUntilChanged().subscribe(onNext:{
    print($0)
})
OUTPUT: 1 2 1 3

Combine

Combinations

StartWith

If you want an Observable to emit a specific sequence of items before it begins emitting the items normally expected from it, use the startWith operator

Merge

You can combine the output of multiple Observables so that they act like a single Observable, by using the Merge operator.

Zip

You use the Zip method if you want to merge items emitted by different observable sequences to one observable sequence.

Side Effects

If you want to register callbacks that will be executed when certain events take place on an Observable Sequence you need to use the doOn Operator. It will not modify the emitted elements but rather just pass them through. You can use …

do(onNext:) - if you want to do something just if a next event happened
do(onError:) - if errors will be emitted and
do(onCompleted:) - if the sequence finished successfully.
Observable.of(1,2,3,4,5).do(onNext: {
    $0 * 10 // This has no effect on the actual subscription
}).subscribe(onNext:{
    print($0)
})

Schedulers

Operators will work on the same thread as where the subscription is created. In RxSwift you use schedulers to force operators do their work on a specific queue. You can also force that the subscription should happen on a specifc Queue. You use subscribeOn and observeOn for those tasks. If you are familiar with the concept of operation-queues or dispatch-queues this should be nothing special for you. A scheduler can be serial or concurrent similar to GCD or OperationQueue. There are 5 Types of Schedulers in RxSwift:

Here is a code snippet that shows you how to observe something concurrently on a background queue und subscribe on the main-queue.

let publish1 = PublishSubject<Int>()
let publish2 = PublishSubject<Int>()
let concurrentScheduler = ConcurrentDispatchQueueScheduler(qos: .background)
Observable.of(publish1,publish2)
          .observeOn(concurrentScheduler)
          .merge()
          .subscribeOn(MainScheduler())
          .subscribe(onNext:{
    print($0)
})
publish1.onNext(20)
publish1.onNext(40)
OUTPUT: 20 40