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

Functional Reactive Programming in Swift

0ebf471a3ae8df42a84f93a7efbbdbd0?s=47 Ash Furrow
October 28, 2014

Functional Reactive Programming in Swift

Take a look at how functional reactive programming works using ReactiveCocoa and Swift. See how to use existing Objective-C APIs with Swift and examine common concepts in functional reactive programming like data transformation, filtering, and binding. Finally, get some resources for how to begin your journey to becoming a ReactiveCocoa expert.

Presented at MBLTDev: http://mbltdev.ru
Sample code: https://github.com/AshFurrow/MBLTDev

0ebf471a3ae8df42a84f93a7efbbdbd0?s=128

Ash Furrow

October 28, 2014
Tweet

More Decks by Ash Furrow

Other Decks in Programming

Transcript

  1. Functional Reactive Programming in Swift Ash  Furrow

  2. Agenda 1. Func'onal  reac've  programming  uses  a  concept  call  “signals”

      2. Reac'veCocoa  uses  signals  to  reduce  mutable  state   3. Ge>ng  started  is  easy
  3. Signals

  4. Signals • At  the  core  of  FRP  are  signals  

    • Signals  send  values  over  'me,  un'l  they  complete  or  error  out   • A  signal  never  sends  anything  aGer  comple'ng  or  erring     • A  signal  either  completes,  or  errors  out,  but  never  both   • A  signal  has  no  concept  of  a  “current  value”  or  “past  values”   • It’s  like  a  pipe
  5. Signals • Signals  can  be  chained  to  transform  the  values

     that  they  send   • This  is  core  to  FRP:  data  transforma'on  of  values  sent  over  'me   • In  math  terms,  it’s  f(g(y))
  6. ReactiveCocoa

  7. None
  8. • Reac'veCocoa  is  a  framework  developed   by  GitHub  

    • Reac'veCocoa  is  an  implementa'on  of   FRP  on  iOS/OS  X   • It’s  currently  being  revamped  with  SwiG  to   version  3.0
  9. Signals • Signals  are  typically  built  on  KVO   •

    They  can  also  be  created  manually   • Crea'ng  a  signal  is  easy   • RACObserve()   • Wraps  a  dynamic  property   • Sends  a  new  value  for  updated  property  values
  10. Signals • Subscribe  to  a  signal  to  perform  side-­‐effects  when

     it  sends  new  values   • Or  use  bindings  (later)
  11. public func RACObserve(target: NSObject!, keyPath: String) -> RACSignal { return

    target.rac_valuesForKeyPath(keyPath, observer: target) } github.com/AshFurrow/Swift-RAC-Macros
  12. let signal = RACObserve(object, "number") signal.subscribeNext { (number) -> Void

    in println("Received \(number)") }
  13. Signal Operators • Signal  operators  transform  the  values  sent  by

     signals   • These  are  func'ons  on  a  signal  that  return  a  new  signal
  14. None
  15. Map • Mapping  performs  a  value  transforma'on  on  the  given

     signal   • It  “maps”  each  value  sent  along  the  signal  to  a  new  value   • It  then  passes  that  new  value  along,  crea'ng  a  new  signal   • This  is  the  canonical  value  transforma'on
  16. let signal = RACObserve(object, “number") signal.map { (number) -> AnyObject!

    in return "\(number)" }.subscribeNext { (string) -> Void in println("Received \(string)") }
  17. let signal = RACObserve(object, “person") signal.map { (object) -> AnyObject!

    in return (object as Person).name }.subscribeNext { (name) -> Void in println(“name: \(name)") }
  18. func toName(person: AnyObject!) -> AnyObject! { return (person as Person).name

    } let signal = RACObserve(object, “person") signal.map(toName).subscribeNext { (name) -> Void in println(“name: \(name)") }
  19. Filter • Filtering  allows  values  that  pass  some  test  to

     “pass  through”
  20. someNumberSignal.filter { (object) -> Bool in return (object as NSNumber)

    > 5 }.subscribeNext { (object) -> Void in return "The number is \(object)" }
  21. Bindings • Bindings  can  bind  a  property  to  the  latest

     value  sent  on  a  signal   • Bindings  are  typically  created  with  the  RAC  func'on   • All  bindings  created  with  the  RAC  func'on  are  one-­‐way   • Bindings  are  the  secret  sauce  that  hold  apps  together
  22. public struct RAC { var target: NSObject var keyPath: String

    var nilValue: AnyObject? public init(_ target: NSObject, _ keyPath: String, nilValue: AnyObject? = nil) { self.target = target self.keyPath = keyPath self.nilValue = nilValue } func assignSignal(signal : RACSignal) -> RACDisposable { return signal.setKeyPath(self.keyPath, onObject: self.target, nilValue: self.nilValue) } } infix operator <~ {} public func <~ (rac: RAC, signal: RACSignal) -> RACDisposable { return signal ~> rac } public func ~> (signal: RACSignal, rac: RAC) -> RACDisposable { return rac.assignSignal(signal) } github.com/AshFurrow/Swift-RAC-Macros
  23. RAC(textField, "text") <~ RACObserve(self, "someString")

  24. Derived State • State  is  avoided  in  Reac'veCocoa,  but  is

     unavoidable  in  Cocoa   • Instead  of  hacky  workarounds,  we  derive  the  state  from  signals   • Similar  to  the  last  example’s  enabled  state  binding
  25. Other Operators • combineLatest()   • takeUn'l()   • scheduleOn()

      • thro_le()   • not(),  and(),  or()
  26. Getting Started

  27. Getting Started • Ge>ng  started  with  Reac'veCocoa  is  easy  

    • Install  Reac'veCocoa  in  your  project  as  a  submodule   • Switch  to  the  swiG-­‐development  branch
  28. Getting Started • Start  by  replacing  KVO  methods  with  RACObserve

      • Use  subscribeNext()  or  doNext()  for  side-­‐effects   • Start  looking  for  opportuni'es  to  replace  state  with  signals
  29. Getting Started • When  create  a  property,  ask  yourself  if

     a  signal  would  be  appropriate   • Is  it  important  to  know  the  value  of  the  property  aGer  it’s  set?   • Are  side-­‐effects  performed  when  it’s  changed?
  30. Demo github.com/AshFurrow/MBLTDev

  31. Demo • No'ce  subscribeNext:  is  used  for  side-­‐effects   •

    Cocoa  Touch  isn’t  built  on  FRP,  so  we  need  side-­‐effects   • Network  results  are  delivered  on  a  background  scheduler   • Use  deliverOn()  to  reschedule  them
  32. github.com/artsy/eidolon

  33. Eidolon • Completely  open  source  iOS  8  SwiG  app  wri_en

     using  Reac'veCocoa   • Lots  of  examples  of  its  use   • Observing  model  proper'es   • User  interface  changes   • Networking  code   • S'll  a  work-­‐in-­‐progress
  34. Getting Started • Start  slowly   • You’re  responsible  for

     this  decision   • Be  prepared  to  answer  ques'ons   • There  is  a  community  to  support  you
  35. Wrap Up 1. Func'onal  reac've  programming  uses  a  concept  call

     “signals”   2. Reac'veCocoa  uses  signals  to  reduce  mutable  state   3. Ge>ng  started  is  easy
  36. http://leanpub.com/iosfrp

  37. @ashfurrow ashfurrow.com