Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to RxSwift

Introduction to RxSwift

This was a presentation I gave at CocoaHeads Johannesburg about RxSwift

Peter-John Welcome

March 19, 2019

More Decks by Peter-John Welcome

Other Decks in Programming


  1. What is Rx: ReactiveX is an API for asynchronous programming

    with observable streams Observable streams (i.e. streams that can be observed) in the context of Reactive Extensions are like event emitters that emit 3 events: next, error, and complete.
  2. History • Started as part of the .NET/C# ecosystem •

    Reactive programming is a programming paradigm oriented around data flows and the propagation of change • Functional Programming
  3. Observables and Observers: • An Observable is something which emits

    notifications of change. • An Observer is something which subscribes to an Observable, in order to be notified when it has changed.
  4. Observables and Observers: • .next(value: T) — When a value or collection

    of values is added to an observable sequence • .error(error: Error) — If an Error is encountered, a sequence will emit an error event. This will also terminate the sequence. • .completed — If a sequence ends normally it sends a completed event to its subscribers
  5. Dispose Bag: • RxSwift and RxCocoa also have an additional

    tool to help deal with ARC and memory management: the DisposeBag. Helps with deallocation of object.
  6. Subjects: • PublishSubject — If you subscribe to it you will get

    all the events that will happen after you subscribed. • BehaviourSubject — A behavior subject will give any subscriber the most recent element and everything that is emitted • ReplaySubject — you can define how many recent items you want to emit to new subscribers
  7. let a = Observable.of(1,2,3,4,5) let b = Observable.of("a","b","c","d") Observable.zip(a,b){ return

    ($0,$1) }.subscribe { print($0) } OUTPUT: [(1, "a"), (2, "b"), (3, "c"), (4, "d")] Transformation: zip
  8. Schedulers: • All operators and observables run on the same

    thread that they are subscribed on. • We can force them on different threads with subscribeOn and observeOn. • It uses operation-ques and dispatch-queues under the hood.
  9. let publish = PublishSubject<Int>() let concurrentScheduler = ConcurrentDispatchQueueScheduler(qos: .background) Observable.of(publish)

    .observeOn(concurrentScheduler) .subscribeOn(MainScheduler()) .subscribe(onNext:{ print($0) }) publish.onNext(20) publish.onNext(40) OUTPUT: 20 40 Schedulers:
  10. searchbar.rx.text.bind(to: viewModel.query).disposed(by: disposeBag) searchbar.rx.searchButtonClicked.asDriver(onErrorJustReturn: ()) .drive(onNext: { [weak self] _

    in self?.viewModel.retrieveStuff() }).disposed(by: disposeBag) searchbar.rx.cancelButtonClicked .map{ _ in "" } .bind(to: viewModel.query) .disposed(by: disposeBag) RxCocoa:
  11. func testStuff() { let dummyData = dummylist() let events =

    [ next(0, dummyData) ] let scheduler = TestScheduler(initialClock: 0) let inputObservable = scheduler.createHotObservable(events).asObservable() let outputObserver = scheduler.createObserver(Array<String>.self) let systemUnderTest = ViewModel() systemUnderTest.query.value = "" } Unit Testing: Setup
  12. func testStuff() { ..... stub(someRepoMock) { mock in when(mock.searchForNames(r:any())).thenReturn(inputObservable) }

    _ = systemUnderTest.results.subscribe(outputObserver) scheduler.start() systemUnderTest.retrieveStuff() verify(someRepoMock , times(1)).searchForNames(r: any()) } } Unit Testing: execution