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

Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift

Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift

This is an introduction to reactive concepts using Swift specifically with ReactiveX’s implementation, RxSwift. ReactiveX is an API for asynchronous programming with observable streams originally implemented with .NET and LINQ. ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming.

You’ll learn about all the basic moving parts of RxSwift and why you want to use it in your application.

Original presented 23-Aug-2016 at 360iDev 2016 - Denver, CO.

Aaron Douglas

August 23, 2016
Tweet

More Decks by Aaron Douglas

Other Decks in Technology

Transcript

  1. WHO I AM ➤ Aaron Douglas ➤ Milwaukee, WI USA

    ➤ Mobile Maker for Automattic (WordPress.com) ➤ Remote full time 3+ years ➤ @astralbodies
  2. FUNCTIONAL & REACTIVE PROGRAMMING ➤ Reactive Programming ➤ Asynchronous Data

    Flow ➤ Functional Programming ➤ Map, Reduce, Filter ➤ Avoiding State ➤ Immutable Data ➤ Declarative Paradigm - logic of computation rather than describing flow ➤ Implementations - ReactiveCocoa/RAC, RxSwift
  3. WHAT IS RXSWIFT? ➤ Based on ReactiveX ➤ Many different

    ports: Java, JavaScript, .NET, Scala, Clojure, Swift, Kotlin, PHP , … ➤ Extends the Observer Pattern ➤ Related to Iterable Pattern ➤ Swift itself provides some protocols with equivalence ➤ SequenceType ➤ GeneratorType
  4. NSNOTIFICATIONCENTER NSNotificationCenter .defaultCenter() .addObserver(self, selector:"downloadImage:", name: "BLDownloadImageNotification", object: nil) NSNotificationCenter

    .defaultCenter() .postNotificationName("BLDownloadImageNotification", object: self, userInfo: ["imageView": coverImage, "coverUrl": albumCover])
  5. GENERATORS class CountdownGenerator: GeneratorType { typealias Element = Int var

    element: Element init<T>(array: [T]) { self.element = array.count } func next() -> Element? { guard element > 0 else { return nil } element -= 1 return element } } let xs = ["A", "B", "C"] let generator = CountdownGenerator(array: xs) while let i = generator.next() { print("Element \(i) of the array is \(xs[i])") } Element 2 of the array is C Element 1 of the array is B Element 0 of the array is A
  6. SEQUENCES class ReverseSequence<T>: SequenceType { var array: [T] init(array: [T])

    { self.array = array } func generate() -> CountdownGenerator { return CountdownGenerator(array: array) } } let reverseSequence = ReverseSequence(array: xs) let reverseGenerator = reverseSequence.generate() while let i = reverseGenerator.next() { print("Index \(i) is \(xs[i])") } for i in ReverseSequence(array: xs) { print("Index \(i) is \(xs[i])") } Index 2 is C Index 1 is B Index 0 is A Index 2 is C Index 1 is B Index 0 is A
  7. OBSERVERTYPE public protocol ObserverType { associatedtype E func on(event: Event<E>)

    } public enum Event<Element> { case Next(Element) case Error(ErrorType) case Completed }
  8. OBSERVABLETYPE public protocol ObservableType : ObservableConvertibleType { associatedtype E func

    subscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable } public protocol ObservableConvertibleType { associatedtype E func asObservable() -> Observable<E> }
  9. MAKING AN OBSERVABLE let disposeBag = DisposeBag() Observable.of("W", "X", "Y",

    "X") .subscribeNext { element in print(element) } .addDisposableTo(disposeBag)
  10. MAKING AN OBSERVABLE let disposeBag = DisposeBag() ["W", "X", "Y",

    "Z"].toObservable() .subscribeNext { print($0) } .addDisposableTo(disposeBag)
  11. SUBSCRIBING someObservable.subscribe( onNext: { print("Element: ", $0) }, onError: {

    print("Error: ", $0) }, onCompleted: { print("Completed") }, onDisposed: { print("Disposed") } ) someObservable .subscribeNext { print("Element: ", $0) }
  12. MAP

  13. MAP let disposeBag = DisposeBag() Observable.of(1, 2, 3) .map {

    $0 * 10 } .subscribeNext { print($0) } .addDisposableTo(disposeBag) --- 10 20 30
  14. FILTER let disposeBag = DisposeBag() Observable.of(2, 30, 22, 5, 60,

    1) .filter { $0 > 10 } .subscribeNext { print($0) } .addDisposableTo(disposeBag) --- 30 22 60
  15. SCAN let disposeBag = DisposeBag() Observable.of(1, 2, 3, 4, 5)

    .scan(0) { aggregateValue, newValue in aggregateValue + newValue } .subscribeNext { print($0) } .addDisposableTo(disposeBag) --- 1 3 6 10 15
  16. MERGE let disposeBag = DisposeBag() let subject1 = PublishSubject<String>() let

    subject2 = PublishSubject<String>() Observable.of(subject1, subject2) .merge() .subscribeNext { print($0) } .addDisposableTo(disposeBag) subject1.onNext("20") subject1.onNext("40") subject1.onNext("60") subject2.onNext("1") subject1.onNext("80") subject1.onNext("100") subject2.onNext("1") 20 40 60 1 80 100 1
  17. BINDINGS ➤ NSTextStorage ➤ UIActivityIndicatorView ➤ UIAlertAction ➤ UIApplication ➤

    UIBarButtonItem ➤ UIButton ➤ UICollectionView ➤ UIControl ➤ UIDatePicker ➤ UIGestureRecognizer ➤ UIImagePickerController ➤ UIImageView ➤ UILabel ➤ UINavigationItem ➤ UIPageControl ➤ UIPickerView ➤ UIProgressView ➤ UIRefreshControl ➤ UIScrollView ➤ UISearchBar ➤ UISearchController ➤ UISegmentedControl ➤ UISlider ➤ UIStepper ➤ UISwitch ➤ UITabBar ➤ UITabBarItem ➤ UITableView ➤ UITextField ➤ UITextView ➤ UIView ➤ UIViewController
  18. WHERE TO LEARN MORE ➤ ReactiveX RxSwift main repo ➤

    https://github.com/ReactiveX/RxSwift/ ➤ FRP iOS Learning Resources ➤ https://gist.github.com/JaviLorbada/4a7bd6129275ebefd5a6 ➤ Functional Reactive Programming with RxSwift ➤ https://realm.io/news/slug-max-alexander-functional-reactive-rxswift/ ➤ RxSwift Slack ➤ http://rxswift-slack.herokuapp.com/