now you're thinking with signals

Upload: jeames

Post on 03-Mar-2016

16 views

Category:

Documents


0 download

DESCRIPTION

A talk on FRP originally presented at the /dev/world/2015 conference.

TRANSCRIPT

  • Now You're Thinking With Signals!

    A ReactiveCocoa Adventure

  • Who is this guy?

    Jeames BoneiOS Software Engineer @ Outware Mobile@jeamesbone on all the things.

  • FunctionalReactive

    Programming

  • What is FRP?

  • F for Functional

    Immutable Stateless

  • R for Reactive

    What instead of how Derived stateInstead of telling a computer how to do its job, why don't we just tell it what it's job is and let it figure the rest out?

  • Functional Reactive Programming Combines functional and reactive paradigms. Uses streams of values and transformations on streams to

    derive state.

  • Why FRPUIs are big, messy, mutable, stateful bags of sadness. Reduce mutable state Simpler programs Better code

  • ReactiveCocoa

  • Signals

  • Events

    public enum Event { /// A value provided by the signal. case Next(T)

    /// The signal terminated because of an error. No further events will be /// received. case Error(E)

    /// The signal successfully terminated. No further events will be received. case Completed

    /// Event production on the signal has been interrupted. No further events /// will be received. case Interrupted}

  • Signals

  • Signals in ReactiveCocoa 3

    Signal

    Signals model an existing stream of events in your app. User input Notifications Location Updates

  • SignalProducers

    SignalProducer

    SignalProducers model the results of some work. Network requests A modal view A watch connectivity request

  • Errors

    Errors are passed on to the next step in the stream. If any point of the stream fails, we can handle this in one

    place. Railway oriented programming

  • OperatorsTo the internet!

  • Example

  • let searchStrings = textField.rac_textSignal() .toSignalProducer() .map { text in text as! String }

  • let searchResults = searchStrings .flatMap(.Latest) { query in let URLRequest = self.searchRequestWithEscapedQuery(query) return NSURLSession.sharedSession().rac_dataWithRequest(URLRequest) } .map { data, URLResponse in let string = String(data: data, encoding: NSUTF8StringEncoding)! return parseJSONResultsFromString(string) } .map { JSONResults in return self.parseModelFromJSON(JSONResults) } .observeOn(UIScheduler())

  • searchResults.start(next: { model in self.updateUIWithModel(model)})

  • Now for magic

  • let searchResults = searchStrings .flatMap(.Latest) { query in let URLRequest = self.searchRequestWithEscapedQuery(query) return NSURLSession.sharedSession().rac_dataWithRequest(URLRequest) .retry(3) .catch { error in self.displayError(error) return SignalProducer.empty } } .map { data, URLResponse in let string = String(data: data, encoding: NSUTF8StringEncoding)! return parseJSONResultsFromString(string) } .map { JSONResults in return self.parseModelFromJSON(JSONResults) } .observeOn(UIScheduler())

  • But wait there's more!

  • let searchStrings = textField.rac_textSignal() .toSignalProducer() .map { text in text as! String } .filter { text in text.characters.count > 4 } .throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler)

  • What has this given us?

    Less code Maintainable code Readable code

  • Where to next? http://reactivecocoa.io/ Try it!

  • Thanks!Questions?