Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

About me

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

What is Rx(ReactiveX)?

Slide 5

Slide 5 text

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.

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

What brought this on?

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Let’s get into RxSwift

Slide 10

Slide 10 text

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.

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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.

Slide 13

Slide 13 text

let observable = Observable.just("Hello World") observable.subscribe(onNext: { myString in print(myString) }).addDisposableTo(disposeBag) Observables and Observers:

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Subjects: let bag = DisposeBag() var publishSubject = PublishSubject() publishSubject.onNext("Hello") publishSubject.subscribe(onNext:{ print($0) }).addDisposableTo(bag)

Slide 17

Slide 17 text

Transformations (functional programming)

Slide 18

Slide 18 text

Transformation: ● map  ● flatMap  ● Scan  ● Filter ● Zip ● Many More

Slide 19

Slide 19 text

Observable.of(1,2,3,4).map { return $0 * 10 }.subscribe(onNext:{ print($0) }) OUTPUT: 10, 20, 30, 40 Transformation: map

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Schedulers

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

Schedulers: ● MainScheduler ● CurrentThreadScheduler ● SerialDispatchQueueScheduler ● ConcurrentDispatchQueueScheduler ● OperationQueueScheduler

Slide 24

Slide 24 text

let publish = PublishSubject() 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:

Slide 25

Slide 25 text

RxCocoa

Slide 26

Slide 26 text

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:

Slide 27

Slide 27 text

Demo Time

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Unit Testing

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

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.self) let systemUnderTest = ViewModel() systemUnderTest.query.value = "" } Unit Testing: Setup

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

Thanks! Contact me: https://medium.com/@pjwelcome @pjapplez [email protected] Peter-johnwelcome.co.za https://github.com/pjwelcome