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

Function Reactive Programming in iOS

Ddd6d3bac7772fa67fc5e312a18bdaec?s=47 sammyd
July 03, 2014

Function Reactive Programming in iOS

A brief overview into functional reactive programming, with some specific use cases in ReactiveCocoa.

Ddd6d3bac7772fa67fc5e312a18bdaec?s=128

sammyd

July 03, 2014
Tweet

More Decks by sammyd

Other Decks in Technology

Transcript

  1. Functional Reactive iOS

  2. Functional Reactive iOS

  3. Functional Reactive OSX

  4. Functional Reactive .NET

  5. Functional Reactive JS

  6. Functional Reactive

  7. Functional Reactive Why you should consider programming

  8. @iwantmyrealname

  9. iwantmyreal.name

  10. leanpub.com/ios7daybyday

  11. @shinobicontrols

  12. shinobicontrols.com

  13. what is functional reactive programming?

  14. what is functional reactive programming?

  15. programming

  16. computer programming is a process that leads from an original

    formulation of a computing problem to executable programs programming
  17. what is functional reactive programming?

  18. functional

  19. functional stateless immutable 1st class functions

  20. what is functional reactive programming?

  21. reactive

  22. reactive dataflow spreadsheets

  23. what is functional reactive programming?

  24. frp obvious

  25. frp immutable events functional pipeline reactive signals

  26. frp a standard interface for events

  27. signals

  28. signals what are

  29. represent a stream of immutable events signals

  30. events are signals next completed error

  31. signals what can model?

  32. delegation observer/databinding target-action blocks/lambdas/closures modelling

  33. async tasks network events user interaction flow control modelling

  34. signals what can be used for?

  35. signals most useful when a functional pipeline is formed uses

  36. map filter combine buffer signal operations zip concat takeUntil …

  37. real world example

  38. demo

  39. example username password s sa sam p pa pas pass

    submit
  40. example username password s sa sam p pa pas pass

    submit username password 1 2 3 1 2 3 4 string.length map
  41. example username password s sa sam p pa pas pass

    submit username password 3 3 4 greater than 2 filter
  42. example let usernameSignal = tf.rac_textSignal() .mapAs({ (value: NSString) -> NSNumber

    in return value.length }) .filterAs({ (value: NSNumber) -> Bool in return value.intValue > 2 })
  43. example let usernameSignal = tf.rac_textSignal() .mapAs({ (value: NSString) -> NSNumber

    in return value.length }) .filterAs({ (value: NSNumber) -> Bool in return value.intValue > 2 })
  44. example let usernameSignal = tf.rac_textSignal() .mapAs({ (value: NSString) -> NSNumber

    in return value.length }) .filterAs({ (value: NSNumber) -> Bool in return value.intValue > 2 })
  45. example RACSignal.combineLatest([usernameSignal, passwordSignal]) .subscribeNext({ (value: AnyObject!) in button.enabled = true

    })
  46. example RACSignal.combineLatest([usernameSignal, passwordSignal]) .subscribeNext({ (value: AnyObject!) in button.enabled = true

    })
  47. more interesting example

  48. example connect to a websocket which streams live edits from

    wikipedia
  49. example RESPONSE: { "type":"unspecified", "content":"Wikipedia talk:Articles for creation/Bonnie ZoBell", “time":"2014-05-15T14:45:59.175Z"

    } RESPONSE: { "type":"unspecified", "content":"Wikipedia:WikiProject Spam/LinkReports/blog.wifirst.fr", “time":"2014-05-15T14:45:59.247Z" } RESPONSE: { "type":"special", "content":"", “time":"2014-05-15T14:46:00.262Z" } RESPONSE: { "type":"unspecified", "content":"Manhattan Film Academy", “time":"2014-05-15T14:46:00.828Z" }
  50. example show the names of the edited pages

  51. filter to get “unspecified” map to extract “content” subscribe and

    update label example
  52. example wsConnector.messages .filterAs({ (dict: NSDictionary) in return (dict["type"] as NSString).isEqualToString("unspecified")

    }) .mapAs({ (dict: NSDictionary) -> NSString in return dict["content"] as NSString }) .deliverOn(RACScheduler.mainThreadScheduler()) .subscribeNextAs({(value: NSString) in self.tickerLabel.text = value })
  53. example wsConnector.messages .filterAs({ (dict: NSDictionary) in return (dict["type"] as NSString).isEqualToString("unspecified")

    }) .mapAs({ (dict: NSDictionary) -> NSString in return dict["content"] as NSString }) .deliverOn(RACScheduler.mainThreadScheduler()) .subscribeNextAs({(value: NSString) in self.tickerLabel.text = value })
  54. example wsConnector.messages .filterAs({ (dict: NSDictionary) in return (dict["type"] as NSString).isEqualToString("unspecified")

    }) .mapAs({ (dict: NSDictionary) -> NSString in return dict["content"] as NSString }) .deliverOn(RACScheduler.mainThreadScheduler()) .subscribeNextAs({(value: NSString) in self.tickerLabel.text = value })
  55. example plot the live edit rate on a chart

  56. buffer to collect sample map to count samples subscribe to

    add to chart example
  57. example wsConnector.messages .bufferWithTime(5, onScheduler: scheduler) .mapAs({ (value: RACTuple) -> NSNumber

    in return NSNumber(double: Double(value.count) / 5.0) }) .deliverOn(RACScheduler.mainThreadScheduler()) .logNext() .subscribeNext({(x: AnyObject!) in self.datasource!.appendValue(x as NSNumber) })
  58. example wsConnector.messages .bufferWithTime(5, onScheduler: scheduler) .mapAs({ (value: RACTuple) -> NSNumber

    in return NSNumber(double: Double(value.count) / 5.0) }) .deliverOn(RACScheduler.mainThreadScheduler()) .logNext() .subscribeNext({(x: AnyObject!) in self.datasource!.appendValue(x as NSNumber) })
  59. example wsConnector.messages .bufferWithTime(5, onScheduler: scheduler) .mapAs({ (value: RACTuple) -> NSNumber

    in return NSNumber(double: Double(value.count) / 5.0) }) .deliverOn(RACScheduler.mainThreadScheduler()) .logNext() .subscribeNext({(x: AnyObject!) in self.datasource!.appendValue(x as NSNumber) })
  60. example annotate new-user events on the chart

  61. filter to get “newuser” map to create annotation subscribe to

    add to chart example
  62. example wsConnector.messages .filterAs({ (value: NSDictionary) -> Bool in return (value["type"]

    as NSString).isEqualToString("newuser") }) .mapAs({ (value: NSDictionary) -> SChartAnnotation in return self.createNewUserAnnotation(value["time"]) }) .deliverOn(RACScheduler.mainThreadScheduler()) .subscribeNextAs({ (value: SChartAnnotation) in self.chart.addAnnotation(value) self.chart.redrawChart() })
  63. example wsConnector.messages .filterAs({ (value: NSDictionary) -> Bool in return (value["type"]

    as NSString).isEqualToString("newuser") }) .mapAs({ (value: NSDictionary) -> SChartAnnotation in return self.createNewUserAnnotation(value["time"]) }) .deliverOn(RACScheduler.mainThreadScheduler()) .subscribeNextAs({ (value: SChartAnnotation) in self.chart.addAnnotation(value) self.chart.redrawChart() })
  64. example wsConnector.messages .filterAs({ (value: NSDictionary) -> Bool in return (value["type"]

    as NSString).isEqualToString("newuser") }) .mapAs({ (value: NSDictionary) -> SChartAnnotation in return self.createNewUserAnnotation(value["time"]) }) .deliverOn(RACScheduler.mainThreadScheduler()) .subscribeNextAs({ (value: SChartAnnotation) in self.chart.addAnnotation(value) self.chart.redrawChart() })
  65. demo

  66. in summary

  67. cool functional reactive programming is

  68. powerful functional reactive programming is

  69. fun functional reactive programming is

  70. you should give it a try

  71. you should give it a try ReactiveCocoa

  72. you should give it a try ReactiveExtensions

  73. you should give it a try Elm

  74. thanks github.com/sammyd @iwantmyrealname