Pro Yearly is on sale from $80 to $50! »

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

B8e8a9c7e39b72963b8ade16d4406a8b?s=128

Frederik Jacques

November 22, 2017
Tweet

Transcript

  1. RxSwift and how we use it in production apps frederik

    jacques - @thenerd_be 1
  2. Hello frederik jacques - @thenerd_be 2

  3. 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
  4. frederik jacques - @thenerd_be 4

  5. RxSwift frederik jacques - @thenerd_be 5

  6. RxSwift • What is it? • Observables / Observers •

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

    api over different language ports frederik jacques - @thenerd_be 7
  8. frederik jacques - @thenerd_be 8

  9. Nutshell definition frederik jacques - @thenerd_be 9

  10. Handling asynchronous code by observing a stream of values. —

    Yours truly frederik jacques - @thenerd_be 10
  11. ! frederik jacques - @thenerd_be 11

  12. Remember notifications? frederik jacques - @thenerd_be 12

  13. 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
  14. ! Observer Observable frederik jacques - @thenerd_be 14

  15. Observable The thing that sends out stuff — Yours truly

    frederik jacques - @thenerd_be 15
  16. Observer The thing that's interested in the data from the

    observable — Yours truly frederik jacques - @thenerd_be 16
  17. 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
  18. frederik jacques - @thenerd_be 18

  19. Types of streams 1. Infinite streams 2. Finite streams •

    Completes • Errors out frederik jacques - @thenerd_be 19
  20. frederik jacques - @thenerd_be 20

  21. frederik jacques - @thenerd_be 21

  22. frederik jacques - @thenerd_be 22

  23. Subjects frederik jacques - @thenerd_be 23

  24. Subjects 1. Variable 2. PublishSubject 3. BehaviorSubject 4. ReplaySubject frederik

    jacques - @thenerd_be 24
  25. Variable • Easiest one to get started with let names

    = Variable<[String]>(["Frederik"]) frederik jacques - @thenerd_be 25
  26. Variable • Get the current value let nameValue = names.value

    frederik jacques - @thenerd_be 26
  27. Variable • Getting updates names.asObservable() .subscribe(onNext: { (theNames) in print(theNames)

    }) frederik jacques - @thenerd_be 27
  28. Variable • Putting elements on the stream names.value.append("Tom") names.value.append("Spencer") frederik

    jacques - @thenerd_be 28
  29. 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
  30. 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
  31. PublishSubject let nameSubject = PublishSubject<String>() nameSubject.onNext("Frederik") nameSubject.subscribe(onNext: { (name) in

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

    = \(name)") }) nameSubject.onNext("Frederik") nameSubject.onNext("Steven") frederik jacques - @thenerd_be 32
  33. 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
  34. 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
  35. 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
  36. ReplaySubjects let nameSubject = ReplaySubject<String>.create(bufferSize: 1) nameSubject.onNext("Frederik") nameSubject.onNext("Steven") nameSubject.subscribe(onNext: {

    (name) in print("Name = \(name)") }) nameSubject.onNext("Spencer") frederik jacques - @thenerd_be 36
  37. Disposebags frederik jacques - @thenerd_be 37

  38. 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
  39. 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
  40. Sharing is caring frederik jacques - @thenerd_be 40

  41. 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
  42. Operators frederik jacques - @thenerd_be 42

  43. Operators • Marble diagrams frederik jacques - @thenerd_be 43

  44. frederik jacques - @thenerd_be 44

  45. Filter • Filter out elements .filter({ (device) -> Bool in

    return device == "iPad" || device == "iPhone" }) frederik jacques - @thenerd_be 45
  46. 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
  47. Take • Take x-number of elements from the start of

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

    the stream frederik jacques - @thenerd_be 48
  49. 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
  50. Combining observables frederik jacques - @thenerd_be 50

  51. CombineLatest • Combine 2 (or more) observables, but only if

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

    another stream frederik jacques - @thenerd_be 52
  53. Debugging frederik jacques - @thenerd_be 53

  54. Debugging Debugging is hard, the most encountered issues 1. it

    doesn't trigger 2. it triggers too much frederik jacques - @thenerd_be 54
  55. Debugging • use debug() operator in the chain frederik jacques

    - @thenerd_be 55
  56. Schedulers frederik jacques - @thenerd_be 56

  57. 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
  58. 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
  59. Schedulers SubscribeOn • Where does the code of the observable

    run frederik jacques - @thenerd_be 59
  60. Unit Testing Quite easy to do • RxTest: Most code

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

    RxSwift Community for more! frederik jacques - @thenerd_be 61
  62. 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
  63. Demo frederik jacques - @thenerd_be 63

  64. Thank you frederik jacques - @thenerd_be 64

  65. Q&A? frederik jacques - @thenerd_be 65