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

Swift Summit San Francisco October 2015

Javier Soto
October 29, 2015

Swift Summit San Francisco October 2015

Introduction to the ideas behind ReactiveCocoa, and why they're valuable.

Javier Soto

October 29, 2015
Tweet

More Decks by Javier Soto

Other Decks in Programming

Transcript

  1. BEFORE func loadAvatar(userID: String, completion: (UIImage?, NSError?) -> ()) {

    requestUserInfo(userID) { user, error in if let user = user { downloadImage(user.avatarURL) { avatar, error in if let avatar = avatar { completion(avatar, nil) } else { completion(nil, error) } } } else { completion(nil, error) } } } 4 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  2. AFTER func requestUserInfo(userID: String) -> Future<User, UserInfoErrorDomain> func downloadImage(URL: NSURL)

    -> Future<UIImage, UserInfoErrorDomain> func loadAvatar(userID: String) -> Future<UIImage, UserInfoErrorDomain> { return requestUserInfo(userID) .map { $0.avatarURL } .andThen(downloadImage) } 5 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  3. ASYNCHRONY IN MOBILE APPLICATIONS > KVO > User data >

    Networking > Gesture recognizers > Animations > Sensors > Mutable State > ... 7 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  4. TL;DR ASYNCHRONOUS CODE IS HARD 9 — "Asynchronous Code with

    ReactiveCocoa" - Javier Soto. March 2015
  5. ASYNCHRONOUS CODE IS HARD > Cancelation > Throttling > Error

    handling > Retrying > Threading > ... 10 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  6. ''THERE HAS TO BE A BETTER WAY!'' 11 — "Asynchronous

    Code with ReactiveCocoa" - Javier Soto. March 2015
  7. That perfection is unattainable is no excuse not to strive

    for it. — Stolen from Nacho's Twitter bio 12 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  8. REACTIVECOCOA IS HARD > Syntax is unfamiliar > Foreign concepts

    > Feels different to traditional Cocoa APIs > Apple's APIs don't use it. 15 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  9. REACTIVECOCOA IS SIMPLE1 > Few concepts > Abstract away complexity

    > One pattern for asynchronous APIs 1 ''Simple made Easy'' - Rich Hickey 16 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  10. CONCEPTS IN COCOA INVOLVED IN ASYNCHRONOUS APIS > Delegation >

    NSOperation > NSNotificationCenter > KVO > Target-Action > Responder chain > Callback blocks 18 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  11. SIGNALS > Next > Failed > Completed > Interrupted 20

    — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  12. Signal VS SignalProducer func doSomethingAndGiveMeTheResult() -> SignalProducer<Result, Error> func observeSomeOnGoingWork()

    -> Signal<NewValue, Error> 22 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  13. RAC'S OPERATORS: DECLARATIVE VS IMPERATIVE let array = ["one", "two",

    "three"] // Imperative var newArray: [String] = [] for string in array { newArray.append(string.uppercaseString) } // Declarative let newArray = array.map { string in return string.uppercaseString } 24 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  14. RAC'S OPERATORS: DECLARATIVE VS IMPERATIVE let throttleInterval: NSTimeInterval = 0.5

    // Imperative func search(query: String, completion: ([SearchResult]?, MyErrorType?) -> ()) var lastSearch: NSDate? // <--- State func didTypeSearchQuery(searchQuery: String) { guard (lastSearch?.timeIntervalSinceNow > throttleInterval) ?? false else { return } lastSearchDate = NSDate() search(searchQuery) { results, error in ... } } // Declarative let searchQuerySignal: Signal<String, NoError> func search(query: String) -> SignalProducer<[SearchResult], MyErrorType> searchQuerySignal.throttle(throttleInterval).flatMap(.Latest, search) 25 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  15. OPERATORS > map > filter > reduce > collect >

    combineLatest > zip > merge / concat / switchToLatest > flatMapError / mapError > retry > throttle 26 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  16. KVO > Crash if object deallocates while being observed. >

    Crash if observe wrong keypath (stringly-typed API) > Possible crash when de-registering > Easy to break parent class (context often misused) > All observations come through one method > Lose contract: "is this KVO-compliant?" 28 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  17. PROPERTY // KVO class MyClass { private(set) dynamic var value:

    Type } let object = MyClass() object.addObserver(self, forKeyPath: "value", options: [], context: ctx) func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [NSObject : AnyObject]?, context: UnsafeMutablePointer<Void>) { /* HAVE FUN!! */ } // PropertyType class MyClass { var value: AnyProperty<Type> } let object = MyClass() object.value.producer.startWithNext { value in ... } 30 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  18. MYTH: "TO USE REACTIVECOCOA, I NEED TO RE-WRITE MY WHOLE

    APP" 31 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  19. CONCLUSIONS > Our tools are imperfect. Strive to reconsider patterns,

    seek better alternatives. > There's value in these abstractions. > ReactiveCocoa can be adopted slowly. 32 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015
  20. REFERENCES > ReactiveCocoa: https://github.com/ReactiveCocoa/ReactiveCocoa > Back to the Futures -

    Me: https://realm.io/news/swift-summit- javier-soto-futures > Functional Reactive Programming in an Imperative World - Nacho Soto: https://realm.io/news/ nacho-soto-functional-reactive-programming > "Simple made Easy" - Rich Hickey: http://www.infoq.com/ presentations/Simple-Made-Easy 33 — "Asynchronous Code with ReactiveCocoa" - Javier Soto. March 2015