Save 37% off PRO during our Black Friday Sale! »

Introduction to RxSwift

Introduction to RxSwift

This was a presentation I gave at CocoaHeads Johannesburg about RxSwift

7cfaab5ac5113201604c3ad16d9a293b?s=128

Peter-John Welcome

March 19, 2019
Tweet

Transcript

  1. Introduction to RxSwift Peter-John Welcome @pjapplez Mobile Engineering Lead

  2. About me

  3. None
  4. What is Rx(ReactiveX)?

  5. 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.
  6. None
  7. What brought this on?

  8. 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
  9. Let’s get into RxSwift

  10. 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.
  11. 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
  12. 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.
  13. let observable = Observable.just("Hello World") observable.subscribe(onNext: { myString in print(myString)

    }).addDisposableTo(disposeBag) Observables and Observers:
  14. None
  15. 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
  16. Subjects: let bag = DisposeBag() var publishSubject = PublishSubject<String>() publishSubject.onNext("Hello")

    publishSubject.subscribe(onNext:{ print($0) }).addDisposableTo(bag)
  17. Transformations (functional programming)

  18. Transformation: • map  • flatMap  • Scan  • Filter •

    Zip • Many More
  19. Observable<Int>.of(1,2,3,4).map { return $0 * 10 }.subscribe(onNext:{ print($0) }) OUTPUT:

    10, 20, 30, 40 Transformation: map
  20. 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
  21. Schedulers

  22. 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.
  23. Schedulers: • MainScheduler • CurrentThreadScheduler • SerialDispatchQueueScheduler • ConcurrentDispatchQueueScheduler •

    OperationQueueScheduler
  24. 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:
  25. RxCocoa

  26. 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:
  27. Demo Time

  28. None
  29. Unit Testing

  30. None
  31. 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
  32. 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
  33. Resources: • https://www.thedroidsonroids.com/blog/ios/rxswift-by-examples-1-t he-basics/ • https://github.com/ReactiveX/RxSwift • https://medium.com/ios-os-x-development/learn-and-master-%EF%B8%8 F-the-basics-of-rxswift-in-10-minutes-818ea6e0a05b •

    https://www.raywenderlich.com/900-getting-started-with-rxswift-an d-rxcocoa • https://en.wikipedia.org/wiki/Reactive_extensions
  34. Thanks! Contact me: https://medium.com/@pjwelcome @pjapplez pjwelcome@gmail.com Peter-johnwelcome.co.za https://github.com/pjwelcome