code europe
TRANSCRIPT
![Page 1: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/1.jpg)
Introduction to Functional Reactive
Programming
@EliSawic
![Page 2: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/2.jpg)
About me
Eliasz SawickiBlog: www.eliaszsawicki.comTwitter: @EliSawic
@EliSawic
![Page 3: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/3.jpg)
Agenda• What is functional reactive programming?
• Working with streams
• ReactiveSwift - Thinking in signals
• Example
@EliSawic
![Page 4: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/4.jpg)
Functional Reactive Programming
@EliSawic
![Page 5: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/5.jpg)
WikipediaFunctional reactive programming (FRP) is a programming paradigm for reactive programming (asynchronous dataflow programming) using the building blocks of functional programming (e.g. map, reduce, filter).
@EliSawic
![Page 6: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/6.jpg)
Reactive Programming
@EliSawic
![Page 7: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/7.jpg)
Functional Programming
@EliSawic
![Page 8: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/8.jpg)
Blocks
@EliSawic
![Page 9: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/9.jpg)
Imperative vs
Declarative
@EliSawic
![Page 10: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/10.jpg)
Imperative
@EliSawic
![Page 11: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/11.jpg)
Imperativelet array = [0, 1, 2, 3, 4, 5]var evenNumbers = [Int]()for element in array { if element % 2 == 0 { evenNumbers.append(element) }}
@EliSawic
![Page 12: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/12.jpg)
Declarative
@EliSawic
![Page 13: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/13.jpg)
Declarativelet array = [0, 1, 2, 3, 4, 5]let evenNumbers = array.filter { $0 % 2 == 0 }
@EliSawic
![Page 14: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/14.jpg)
Working with streams
@EliSawic
![Page 15: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/15.jpg)
Stream
@EliSawic
![Page 16: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/16.jpg)
Manipulating streams
@EliSawic
![Page 17: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/17.jpg)
Map
@EliSawic
![Page 18: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/18.jpg)
Filter
@EliSawic
![Page 19: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/19.jpg)
Aggregating
@EliSawic
![Page 20: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/20.jpg)
Manipulating multiple streams
@EliSawic
![Page 21: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/21.jpg)
Combine latest
@EliSawic
![Page 22: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/22.jpg)
Merge
@EliSawic
![Page 23: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/23.jpg)
Chaining streams
@EliSawic
![Page 24: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/24.jpg)
www.rxmarbles.com
@EliSawic
![Page 25: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/25.jpg)
ReactiveSwift
@EliSawic
![Page 26: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/26.jpg)
Thinking in Signals
@EliSawic
![Page 27: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/27.jpg)
What is a signal?
@EliSawic
![Page 28: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/28.jpg)
This screen is a signal
@EliSawic
![Page 29: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/29.jpg)
Represents events over time
@EliSawic
![Page 30: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/30.jpg)
Observing does not trigger side effects
@EliSawic
![Page 31: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/31.jpg)
No random access to events
@EliSawic
![Page 32: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/32.jpg)
Observe
@EliSawic
![Page 33: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/33.jpg)
If you don't listen, it's gone
@EliSawic
![Page 34: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/34.jpg)
What is event?
@EliSawic
![Page 35: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/35.jpg)
Eventstruct Idea { var content: String var quality: Quality}
enum Quality { case Great case Average case Worst}
@EliSawic
![Page 36: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/36.jpg)
Non-Terminating• Next
@EliSawic
![Page 37: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/37.jpg)
Terminating
• Completed
• Failed
• Interrupted (Reactive Cocoa)
@EliSawic
![Page 38: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/38.jpg)
Presentationlet (presentation, presentationObserver) = Signal<Idea, NoError>.pipe()
let content = "This presentation is a signal"let idea = Idea(content: content, quality: .Great)
presentationObserver.send(value: idea)presentationObserver.sendCompleted()
@EliSawic
![Page 39: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/39.jpg)
Observingpresentation.observeValues { idea in remember(idea: idea)}presentation.observeCompleted { print("Time for a break")}
@EliSawic
![Page 40: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/40.jpg)
Only great ideaslet greatIdeas = presentation.filter { idea in idea.quality == .Great}greatIdeas.observeValues { greatIdea in remember(idea: greatIdea)}
@EliSawic
![Page 41: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/41.jpg)
Positive listenerlet greatPresentation = presentation.map { idea -> Idea in var greatIdea = idea greatIdea.quality = .Great return greatIdea}
@EliSawic
![Page 42: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/42.jpg)
Signal producer
@EliSawic
![Page 43: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/43.jpg)
Represents a tasks
@EliSawic
![Page 44: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/44.jpg)
Possible side effects
@EliSawic
![Page 45: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/45.jpg)
Does not start it's work if not asked
@EliSawic
![Page 46: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/46.jpg)
Run presentationfunc runPresentation() -> SignalProducer<Idea, NoError> { return SignalProducer { observer, _ in observer.send(value: idea1) observer.send(value: idea2) ... observer.sendCompleted() }}
@EliSawic
![Page 47: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/47.jpg)
Work with presentationrunPresentation().startWithValues { idea in print(idea)}
runPresentation().startWithSignal { (signal, _) in signal.observeValues({ idea in print(idea) })
signal.observeCompleted { print("Finally...") }}
@EliSawic
![Page 48: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/48.jpg)
Cold vs Hot
@EliSawic
![Page 49: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/49.jpg)
Properties
@EliSawic
![Page 50: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/50.jpg)
Mutable Propertylet firstSlide = Slide(number: 1)let slide = MutableProperty<Slide>(firstSlide)slide.producer.startWithValues { (text) in print(text)}slide.value = Slide(number: 2)
@EliSawic
![Page 51: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/51.jpg)
Bindings
@EliSawic
![Page 52: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/52.jpg)
Binding examplelet slideNumber = MutableProperty<Int>(0)let (signal, _) = Signal<Slide, NoError>.pipe()
slideNumber <~ signal.map { return $0.number }
@EliSawic
![Page 53: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/53.jpg)
Binding examplelet (signal, _) = Signal<Slide, NoError>.pipe()
label.reactive.text <~ signal.map { return "Slide: \($0.number)" }
@EliSawic
![Page 54: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/54.jpg)
Schedulers
@EliSawic
![Page 55: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/55.jpg)
Know where you aresignal.observe(on: QueueScheduler.main).observeValues { idea in print("Performing UI updates")}
@EliSawic
![Page 56: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/56.jpg)
Memory Management
@EliSawic
![Page 57: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/57.jpg)
Disposables
@EliSawic
![Page 58: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/58.jpg)
Free your memorylet disposable = signal.observeValues { value in ...}
disposable.dispose()
@EliSawic
![Page 59: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/59.jpg)
Release your producerslet disposable = producer.startWithValues { value in ...}
disposable.dispose()
@EliSawic
![Page 60: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/60.jpg)
Example
@EliSawic
![Page 61: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/61.jpg)
@EliSawic
![Page 62: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/62.jpg)
How does it work?
@EliSawic
![Page 63: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/63.jpg)
Is name valid?let isValidNameSignal = nameSignal.map { (name) -> Bool in return name.characters.count > 2}
@EliSawic
![Page 64: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/64.jpg)
Is surname valid?let isValidSurnameSignal = surnameSignal.map { (surname) -> Bool in return surname.characters.count > 2}
@EliSawic
![Page 65: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/65.jpg)
Is mail valid?let isValidMailSignal = mailSignal.map { (mail) -> Bool in let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) return emailTest.evaluateWithObject(mail)}
@EliSawic
![Page 66: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/66.jpg)
Combine Latestlet formDataSignal = combineLatest( isValidNameSignal, isValidSurnameSignal, isValidMailSignal)
@EliSawic
![Page 67: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/67.jpg)
Is form valid?let isValidFormSignal = formDataSignal.map { (isValidName, isValidSurname, isValidMail) -> Bool in return isValidMail && isValidSurname && isValidMail}
@EliSawic
![Page 68: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/68.jpg)
Update the stateisValidFormSignal.observeValues { isValid in updateButtonWith(state: isValid)}
@EliSawic
![Page 69: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/69.jpg)
Bindinglet isValidForm = MutableProperty<Bool>(false)
isValidForm <~ isFormValidSignal
@EliSawic
![Page 70: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/70.jpg)
Conclusion
@EliSawic
![Page 71: Code europe](https://reader031.vdocument.in/reader031/viewer/2022021922/58729eda1a28ab07208b54c3/html5/thumbnails/71.jpg)
Thank you for your attention!sendCompleted()
@EliSawic