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

A gentle introduction to RxSwift

52edc3d953e8df9d23c2943542f151bc?s=47 Guillermo Gonzalez
June 11, 2016
650

A gentle introduction to RxSwift

https://github.com/gonzalezreal/rxswift-gentle-introduction

Swift has prompted the adoption of functional programming idioms and styles among app developers. If you have been running from this “functional weirdness” it is time to stop and embrace it.

Reactive Functional Programming is one of these idioms, and it is becoming quite popular thanks to ReactiveX (also known as Rx) and its Swift incarnation, RxSwift.

52edc3d953e8df9d23c2943542f151bc?s=128

Guillermo Gonzalez

June 11, 2016
Tweet

Transcript

  1. RxSwift A gentle introduction “RxSwift, A gentle introduction” - Guille

    González @gonzalezreal
  2. Guille González @gonzalezreal “RxSwift, A gentle introduction” - Guille González

    @gonzalezreal
  3. http://reactivex.io “RxSwift, A gentle introduction” - Guille González @gonzalezreal

  4. Observer on steroids “RxSwift, A gentle introduction” - Guille González

    @gonzalezreal
  5. Taps, keyboard events, timers, GPS events, web service responses ↓

    UI update, data written to disk, API request, etc. “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  6. Asynchronous Events in Cocoa → Target-Action → NSNotificationCenter → Key-Value

    Observing → Delegates → Callback Closures “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  7. Observable<Element> “RxSwift, A gentle introduction” - Guille González @gonzalezreal

  8. --1--2--3--4--5-|---> --a--b--b--a--✕-----> ---tap-tap----tap---> ---JSON-|-----------> -|------------------> -✕------------------> “RxSwift, A gentle introduction”

    - Guille González @gonzalezreal
  9. enum Event<Element> { case Next(Element) case Error(ErrorType) case Completed }

    “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  10. --Next("a")--Next("b")--Error(diskError)-> -----Next---Next-------Next--------------> ---Next(json)-Completed------------------> “RxSwift, A gentle introduction” - Guille González

    @gonzalezreal
  11. Creating Observables → Observable.empty() → Observable.just("!") → Observable.of("!", """, "⚽")

    → Observable.error(Error.CouldNotDecodeJSON) “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  12. Creating Observables let o = Observable.create { observer in observer.on(.Next("!

    world!")) observer.on(.Completed) return NopDisposable.instance } “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  13. If a tree falls in a forest and no one

    is around to hear it, does it make a sound? — George Berkeley “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  14. ┌─────────────────────────────────────┬─────────────────────────────────────┐ │ Hot Observables │ Cold observables │ ├─────────────────────────────────────┼─────────────────────────────────────┤ │Use

    resources even when there are no │Don't use resources until there is a │ │subscribers. │subscriber. │ ├─────────────────────────────────────┼─────────────────────────────────────┤ │Resources usually shared between all │Resources usually allocated per │ │the subscribers. │subscriber. │ ├─────────────────────────────────────┼─────────────────────────────────────┤ │Usually stateful. │Usually stateless. │ ├─────────────────────────────────────┼─────────────────────────────────────┤ │UI controls, taps, sensors, etc. │HTTP request, async operations, etc. │ └─────────────────────────────────────┴─────────────────────────────────────┘ “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  15. Observers protocol ObservableType { func subscribe(on: (event: Event) -> Void)

    -> Disposable } “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  16. Observers Observable.create { observer in observer.onNext("! world!") observer.onCompleted() return NopDisposable.instance

    }.subscribe { event in print(event) } // outputs: // Next(! world!) // Completed “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  17. Observers Observable.create { observer in observer.onNext("! world!") observer.onCompleted() return NopDisposable.instance

    }.subscribeNext { text in print(text) } // outputs: // ! world! “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  18. Disposables let appleWeb = Observable.create { observer in let task

    = session.dataTaskWithURL(appleURL) { data, response, error in if let data = data { observer.onNext(data) observer.onCompleted() } else { observer.onError(error ?? Error.UnknownError) } } task.resume() return AnonymousDisposable { task.cancel() } } “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  19. Dispose Bags self.disposeBag = DisposeBag() ... appleWeb.subscribeNext { data in

    print(data) }.addDisposableTo(disposeBag) “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  20. Operators → map → flatMap → filter → throttle →

    merge → combineLatest → and many more... “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  21. map & flatMap struct Country { let name: String let

    borders: [String] } protocol CountriesAPI { func countryWithName(name: String) -> Observable<Country> func countriesWithCodes(codes: [String]) -> Observable<[Country]> } “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  22. map & flatMap myAPI.countryWithName("spain") .flatMap { country in myAPI.countriesWithCodes(country.borders) }

    .map { countries in countries.map { $0.name } } .subscribeNext { countryNames in print(countryNames) } “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  23. Observable chaining is similar to Optional chaining: let cell =

    UITableViewCell(style: .Default, reuseIdentifier: nil) let maybeSize = cell.imageView?.image?.size let maybeSize2 = cell.imageView.flatMap { $0.image }.flatMap { $0.size } “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  24. observeOn myAPI.countryWithName("spain") .flatMap { country in myAPI.countriesWithCodes(country.borders) } .map {

    countries in countries.map { $0.name } } .observeOn(MainScheduler.instance) .subscribeNext { countryNames in // Main thread, all good } “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  25. “RxSwift, A gentle introduction” - Guille González @gonzalezreal

  26. throttle let results = searchBar.rx_text .throttle(0.3, scheduler: MainScheduler.instance) .flatMapLatest {

    query in if query.isEmpty { return Observable.just([]) } return searchShows(query) } .observeOn(MainScheduler.instance) .shareReplay(1) “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  27. combineLatest Observable.combineLatest(emailField.rx_text, passwordField.rx_text) { email, password in return email.characters.count >

    0 && password.characters.count > 0 } .bindTo(sendButton.rx_enabled) .addDisposableTo(disposeBag) “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  28. Follow-up Resources → reactivex.io → rxmarbles.com → github.com/ReactiveX/RxSwift → tinyurl.com/consuming-web-services

    “RxSwift, A gentle introduction” - Guille González @gonzalezreal
  29. Questions? Comments? “RxSwift, A gentle introduction” - Guille González @gonzalezreal