#MBLTdev: Разработка на Swift (Ash Furrow)
description
Transcript of #MBLTdev: Разработка на Swift (Ash Furrow)
![Page 1: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/1.jpg)
Functional Reactive Programming in Swift
Ash Furrow
![Page 2: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/2.jpg)
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
![Page 3: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/3.jpg)
Signals
![Page 4: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/4.jpg)
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
![Page 5: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/5.jpg)
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))
![Page 6: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/6.jpg)
ReactiveCocoa
![Page 7: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/7.jpg)
• 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
![Page 8: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/8.jpg)
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
![Page 9: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/9.jpg)
Signals
• Subscribe to a signal to perform side-‐effects when it sends new values
• Or use bindings (later)
![Page 10: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/10.jpg)
public func RACObserve(target: NSObject!, keyPath: String) -> RACSignal { return target.rac_valuesForKeyPath(keyPath, observer: target) }
github.com/AshFurrow/Swift-RAC-Macros
![Page 11: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/11.jpg)
let signal = RACObserve(object, "number")
signal.subscribeNext { (number) -> Void in println("Received \(number)") }
![Page 12: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/12.jpg)
Signal Operators
• Signal operators transform the values sent by signals
• These are func'ons on a signal that return a new signal
![Page 13: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/13.jpg)
![Page 14: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/14.jpg)
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
![Page 15: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/15.jpg)
let signal = RACObserve(object, “number")
signal.map { (number) -> AnyObject! in return "\(number)" }.subscribeNext { (string) -> Void in println("Received \(string)") }
![Page 16: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/16.jpg)
let signal = RACObserve(object, “person")
signal.map { (object) -> AnyObject! in return (object as Person).name }.subscribeNext { (name) -> Void in println(“name: \(name)") }
![Page 17: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/17.jpg)
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)") }
![Page 18: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/18.jpg)
Filter
• Filtering allows values that pass some test to “pass through”
![Page 19: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/19.jpg)
someNumberSignal.filter { (object) -> Bool in return (object as NSNumber) > 5 }.subscribeNext { (object) -> Void in return "The number is \(object)" }
![Page 20: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/20.jpg)
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
![Page 21: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/21.jpg)
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
![Page 22: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/22.jpg)
RAC(textField, "text") <~ RACObserve(self, "someString")
![Page 23: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/23.jpg)
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
![Page 24: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/24.jpg)
Other Operators
• combineLatest()
• takeUn'l()
• scheduleOn()
• thro_le()
• not(), and(), or()
![Page 25: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/25.jpg)
Getting Started
![Page 26: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/26.jpg)
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
![Page 27: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/27.jpg)
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
![Page 28: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/28.jpg)
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?
![Page 29: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/29.jpg)
Demo github.com/AshFurrow/MBLTDev
![Page 30: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/30.jpg)
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
![Page 31: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/31.jpg)
github.com/artsy/eidolon
![Page 32: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/32.jpg)
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
![Page 33: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/33.jpg)
Getting Started
• Start slowly
• You’re responsible for this decision
• Be prepared to answer ques'ons
• There is a community to support you
![Page 34: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/34.jpg)
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
![Page 36: #MBLTdev: Разработка на Swift (Ash Furrow)](https://reader033.fdocuments.net/reader033/viewer/2022052622/558d1a22d8b42af6058b45c3/html5/thumbnails/36.jpg)
@ashfurrow ashfurrow.com