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

RxSwift - A primer

RxSwift - A primer

The slides for a talk I gave at CocoaHeads Belgium on November 22, 2017 about RxSwift.
The demo project can be found at https://github.com/frederik-jacques/cocoaheads-rxswift-primer

Frederik Jacques

November 22, 2017
Tweet

Other Decks in Programming

Transcript

  1. Hello • Frederik Jacques • Lecturer Devine (Howest University College)

    • Living in The Netherlands (what was I thinking) • Freelance iOS consultant • Currently working at Nederlandse Spoorwegen frederik jacques - @thenerd_be 3
  2. RxSwift • What is it? • Observables / Observers •

    Subjects • Operators • Debugging • Unit Testing • Live demo frederik jacques - @thenerd_be 6
  3. RxSwift • Reactive library • Part of http://reactivex.io • Same

    api over different language ports frederik jacques - @thenerd_be 7
  4. Handling asynchronous code by observing a stream of values. —

    Yours truly frederik jacques - @thenerd_be 10
  5. Here we are observing a certain event. NotificationCenter.default .addObserver( forName:

    Notification.Name.UserDidLogin, object: self, queue: nil ) { (notification) in print("User did login") } frederik jacques - @thenerd_be 13
  6. Observer The thing that's interested in the data from the

    observable — Yours truly frederik jacques - @thenerd_be 16
  7. Observable • The key element of RxSwift • Concept? •

    Produce a sequence of immutable events • 3 types of event: next, completed & error frederik jacques - @thenerd_be 17
  8. Types of streams 1. Infinite streams 2. Finite streams •

    Completes • Errors out frederik jacques - @thenerd_be 19
  9. Variable • Easiest one to get started with let names

    = Variable<[String]>(["Frederik"]) frederik jacques - @thenerd_be 25
  10. Variable • Putting it all together let names = Variable<[String]>(["Frederik"])

    names.asObservable() .subscribe(onNext: { (theNames) in print(theNames) }) names.value.append("Tom") names.value.append("Spencer") frederik jacques - @thenerd_be 29
  11. PublishSubject • Subscribers get all the upcoming events (NOT the

    current one) let nameSubject = PublishSubject<String>() • Add data on the stream with onNext method nameSubject.onNext("Frederik") frederik jacques - @thenerd_be 30
  12. PublishSubject let nameSubject = PublishSubject<String>() nameSubject.onNext("Frederik") nameSubject.subscribe(onNext: { (name) in

    print("Name = \(name)") }) nameSubject.onNext("Steven") frederik jacques - @thenerd_be 31
  13. PublishSubject let nameSubject = PublishSubject<String>() nameSubject.subscribe(onNext: { (name) in print("Name

    = \(name)") }) nameSubject.onNext("Frederik") nameSubject.onNext("Steven") frederik jacques - @thenerd_be 32
  14. BehaviorSubject • Subscribers get all upcoming events + the current

    value let nameSubject = BehaviorSubject<String>(value: "Frederik") • Add data on the stream with onNext method nameSubject.onNext("Steven") frederik jacques - @thenerd_be 33
  15. BehaviorSubject let nameSubject = BehaviorSubject<String>(value: "Frederik") nameSubject.onNext("Steven") nameSubject.subscribe(onNext: { (name)

    in print("Name = \(name)") }) nameSubject.onNext("Spencer") frederik jacques - @thenerd_be 34
  16. ReplaySubject • Subscribers get all upcoming events + the amount

    specified in the buffer from earlier events let nameSubject = ReplaySubject<String>.create(bufferSize: 2) • Add data on the stream with onNext method nameSubject.onNext("Frederik") frederik jacques - @thenerd_be 35
  17. Disposebags A container in which your subscriptions are stored, so

    they don't get deallocated within the local scope of a function or get properly disposed when you class gets deallocated frederik jacques - @thenerd_be 38
  18. Disposebags // Somewhere at the top private let disposeBag =

    DisposeBag() /////// // Somewhere else let nameSubject = ReplaySubject<String>.create(bufferSize: 1) nameSubject.onNext("Frederik") nameSubject.onNext("Steven") nameSubject.subscribe(onNext: { (name) in print("Name = \(name)") }).disposed(by: disposeBag) nameSubject.onNext("Spencer") frederik jacques - @thenerd_be 39
  19. Sharing is caring • Every subscription, triggers the observable •

    Share an observable to avoid this (e.g. network requests) • share() • share(replay: 1, scope: .forever) • share(replay: 1, scope: .whileConnected) frederik jacques - @thenerd_be 41
  20. Filter • Filter out elements .filter({ (device) -> Bool in

    return device == "iPad" || device == "iPhone" }) frederik jacques - @thenerd_be 45
  21. Map • Map from one thing to something else Observable.just(

    18 ) .map { (age) -> String in guard age > 16 else { return "Not allowed to drink" } return "Allowed to drink" } frederik jacques - @thenerd_be 46
  22. Take • Take x-number of elements from the start of

    the stream and complete frederik jacques - @thenerd_be 47
  23. Skip • Skip x-number of elements before receiving elements on

    the stream frederik jacques - @thenerd_be 48
  24. Distinct • Only allow unique elements in the stream •

    Use distinctUntilChanged if doubles are allowed, but not one after each other frederik jacques - @thenerd_be 49
  25. CombineLatest • Combine 2 (or more) observables, but only if

    both have emitted at least one element frederik jacques - @thenerd_be 51
  26. WithLatestFrom • Request the value of the last element of

    another stream frederik jacques - @thenerd_be 52
  27. Debugging Debugging is hard, the most encountered issues 1. it

    doesn't trigger 2. it triggers too much frederik jacques - @thenerd_be 54
  28. Schedulers • Have nothing to do with threading • A

    context where a process takes place (can be a thread, dispatch_queue, NSOperation, ...). frederik jacques - @thenerd_be 57
  29. Schedulers ObserveOn • Where does the code of the observer

    run • 99% of the cases, you'll be using this one frederik jacques - @thenerd_be 58
  30. Unit Testing Quite easy to do • RxTest: Most code

    • RxBlocking: Block thread until you get result frederik jacques - @thenerd_be 60
  31. RxSwift add-ons • RxCocoa • RxSwiftExt • RxDataSources • Check

    RxSwift Community for more! frederik jacques - @thenerd_be 61
  32. Great resources • Slack Channel • RxSwift Book (Ray Wenderlich)

    • Marin Todorov's blog • Droids on roids blog • Rx.playground (in RxSwift GitHub repo) frederik jacques - @thenerd_be 62