SlideShare a Scribd company logo
Reactive Programming Patterns
with RxSwift
Florent Pillet — @fpillet
FrenchKit Conference Paris — September 23rd, 2016
Agenda
• Introduction to Rx
• Creating observable sequences
• Basic patterns
• User interface patterns
• Architecture patterns
About Rx
• Microsoft Reactive Extensions (Rx.NET) - 2009
• ReactiveX.io defines a common API for Rx implementations
• RxSwift 2015
• Shares concepts and API with other implementations
• Heavily tested framework
Reactive Programming Patterns with RxSwift
Base concepts
Asynchronous observable sequences
Base concepts
• Compose and transform observable sequences using
operators
• Rx models the asynchronous propagation of change
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
What did we just see?
• a sequence emitted one item then completed,
• the map operator transformed a sequence of JSON objects
into a sequence of Floats,
• similar to Swift sequence mapping but asynchronous.
What did we just see?
Experiment with interactive marble diagrams
at rxmarbles.com
Observable sequence lifecycle
let disposable = someObservable.subscribe(
onNext: { print("value: ($0)") },
onCompleted: { print("completed") },
)
Observable sequence lifecycle
let disposable = someObservable.subscribe(
onNext: { print("value: ($0)") },
onError: { print("error ($0)") },
onCompleted: { print("completed") }
)
Observable sequence lifecycle
let disposable = someObservable.subscribe(
onNext: { print("value: ($0)") },
onError: { print("error ($0)") },
onCompleted: { print("completed") },
onDisposed: { print("disposed") }
)
// at any point, cancel your subscription
// by calling dispose()
disposable.dispose()
The mysterious genesis of the Observable
The mysterious genesis of the Observable
RxCocoa
import RxCocoa
let disposable = NSNotificationCenter.defaultCenter()
.rx_notification(UIApplicationSignificantTimeChangeNotification)
.subscribeNext {
(notification: UINotification) in
print("Date changed: time to update!")
}
The mysterious genesis of the
Observable
RxCocoa
import RxCocoa
@IBOutlet var textField : UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let _ = textField.rx_text.subscribeNext {
(text: String) in
print("text field changed to (text)")
}
}
The mysterious genesis of the
Observable
Manual creation
let strings : Observable<Int> =
Observable.create { observer in
observer.onNext("Hello")
observer.onNext("World")
observer.onCompleted()
// we don't need to release any
// resource on dispose()
return NopDisposable.instance
}
The mysterious genesis of the Observable
Manual creation
let asyncComputation : Observable<Data> =
Observable.create { observer in
let task = someAsyncTask()
task.run(
success: {
(result: Data) in
observer.onNext(result)
observer.onCompleted()
}
error: {
(error: ErrorType) in
observer.onError(error)
}
)
return AnonymousDisposable {
task.cancel()
}
}
The mysterious genesis of the Observable
More ways to obtain observables:
• Items from an array or collection
• DelegateProxy
• rx_observe(type, keypath, options)
• rx_sentMessage(#selector)
• Subject (stateless) and Variable (stateful)
Basic Patterns
Composition
Task: update temperature label when button tapped
func getTemperature(city: String)
-> Observable<(String,Float)>
func formattedTemperature(temp: Float)
-> String
let disposable = button.rx_tap
.withLatestFrom(textField.rx_text)
.flatMapLatest {
(city: String) -> Observable<(String,Float)> in
return getTemperature(city)
}
.subscribeNext {
(temp: (String,Float)) in
let degrees = formattedTemperature(temp.1)
label.text = "It's (degrees) in (temp.0)"
}
Aggregation
Task: obtain the current temperature in multiple cities
let disposable = ["Berlin","London",
"Madrid","Paris",
"Rome"]
.map {
(city: String) -> Observable<(String,Float)> in
return getTemperature(city)
}
.toObservable()
.merge()
.toArray()
.subscribeNext {
(temperatures: [(String,Float)]) in
// we get the result of the five requests
// at once in a nice array!
}
Cancellation
Task: update temperature every second until VC disappears
var timerDisposable : Disposable!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
timerDisposable = Observable
.timer(0.0, period: 60.0, scheduler: MainScheduler.instance)
.flatMap { _ -> Observable<String> in
getTemperature("Paris").map {
(temp: (String,Float)) -> String in
return String(temp.1)
}
}
.bindTo(label.rx_text)
}
override func viewWillDisappear(animated: Bool) {
timerDisposable.dispose()
super.viewWillDisappear(animated)
}
Error handling
Task: if a temperature network request fails, display "--"
func getTemperatureAsString(city: String) -> Observable<(String,String)> {
return getTemperature(city)
.map {
(temp: (String,Float)) -> String in
return (city, formattedTemperature(temp.1))
}
.catchErrorJustReturn((city, "--"))
}
Error handling
Task: if a temperature network request fails, display "--"
let disposable = button.rx_tap
.withLatestFrom(textField.rx_text)
.flatMapLatest {
(city: String) -> Observable<(String,String)> in
return getTemperatureAsString(city)
}
.map {
(temp: (String,String)) -> String in
return "It's (temp.1) in (temp.0)"
}
.bindTo(label.rx_text)
User interface
patterns
Driver
let disposable = button.rx_tap
.withLatestFrom(textField.rx_text)
.flatMapLatest {
(city: String) -> Driver<String> in
return getTemperature(city)
.map { formattedTemperature($0.1) }
.asDriver(onErrorJustReturn: "--")
}
.drive(label.rx_text)
Action
• not technically part of RxSwift
• an important pattern for binding the UI
• pod Action
• a very useful pattern for MVVM
Action
import Action
lazy var getTemperatureAction : CocoaAction = CocoaAction {
[unowned self] in
return self.getTemperatureAsString(self.textfield.text)
}
button.rx_action = getTemperatureAction
getTemperatureAction.elements.bindTo(label.rx_text)
Architecture patterns
Architecture patterns
• Expose all data to display as Observable sequences
• Use Action to wire up the UI whenever possible
• MVVM is a perfect fit for Rx
Architecture patterns
• Decouple application logic from application infrastructure
• Storage, geolocation, network requests, image cache etc.
are a good fit for insulation
• Makes replacing whole parts of the app easier
• Testing and mocking are easier too
Summary
Reactive programming
• Powerful way to express program logic
• Model the asynchronous propagation of change
• Eliminate state from your code
• Code is more testable
• RxSwift is a solid foundation
• Fast growing pool of users, add-ons and contributors
(RxSwiftCommunity!)
Links
• RxSwift source github.com/reactivex/rxswift
• Community projects github.com/RxSwiftCommunity
• Artsy's Eidolon app github.com/artsy/eidolon
• ReactiveX website reactivex.io
• RxMarbles rxmarbles.com
Q & A

More Related Content

PDF
Reactive programming with RxSwift
Scott Gardner
 
PDF
Reactive Programming with RxSwift
Scott Gardner
 
PDF
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Aaron Douglas
 
PDF
Functional Reactive Programming - RxSwift
Rodrigo Leite
 
PDF
Cascadia.js: Don't Cross the Streams
mattpodwysocki
 
PDF
Swift Sequences & Collections
CocoaHeads France
 
PDF
Angular and The Case for RxJS
Sandi Barr
 
PDF
Reactive, component 그리고 angular2
Jeado Ko
 
Reactive programming with RxSwift
Scott Gardner
 
Reactive Programming with RxSwift
Scott Gardner
 
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Aaron Douglas
 
Functional Reactive Programming - RxSwift
Rodrigo Leite
 
Cascadia.js: Don't Cross the Streams
mattpodwysocki
 
Swift Sequences & Collections
CocoaHeads France
 
Angular and The Case for RxJS
Sandi Barr
 
Reactive, component 그리고 angular2
Jeado Ko
 

What's hot (20)

PPTX
Rxjs ppt
Christoffer Noring
 
PDF
Introduction to RxJS
Brainhub
 
PDF
Map kit light
CocoaHeads France
 
PDF
Oop assignment 02
MamoonKhan39
 
PDF
Understanding Asynchronous JavaScript
jnewmanux
 
PPTX
Rxjs ngvikings
Christoffer Noring
 
PDF
Introduction to reactive programming & ReactiveCocoa
Florent Pillet
 
PPTX
Luis Atencio on RxJS
Luis Atencio
 
PDF
RxJS Evolved
trxcllnt
 
PDF
RxJS 5 in Depth
C4Media
 
PDF
Intro to RxJava/RxAndroid - GDG Munich Android
Egor Andreevich
 
PDF
Realm.io par Clement Sauvage
CocoaHeads France
 
PDF
RxJS101 - What you need to know to get started with RxJS tomorrow
Viliam Elischer
 
PDF
RxJS - The Reactive extensions for JavaScript
Viliam Elischer
 
PPTX
Angular2 rxjs
Christoffer Noring
 
PPTX
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
PDF
Callbacks and control flow in Node js
Thomas Roch
 
PDF
You will learn RxJS in 2017
名辰 洪
 
PPTX
Avoiding Callback Hell with Async.js
cacois
 
PPTX
Rxjs swetugg
Christoffer Noring
 
Introduction to RxJS
Brainhub
 
Map kit light
CocoaHeads France
 
Oop assignment 02
MamoonKhan39
 
Understanding Asynchronous JavaScript
jnewmanux
 
Rxjs ngvikings
Christoffer Noring
 
Introduction to reactive programming & ReactiveCocoa
Florent Pillet
 
Luis Atencio on RxJS
Luis Atencio
 
RxJS Evolved
trxcllnt
 
RxJS 5 in Depth
C4Media
 
Intro to RxJava/RxAndroid - GDG Munich Android
Egor Andreevich
 
Realm.io par Clement Sauvage
CocoaHeads France
 
RxJS101 - What you need to know to get started with RxJS tomorrow
Viliam Elischer
 
RxJS - The Reactive extensions for JavaScript
Viliam Elischer
 
Angular2 rxjs
Christoffer Noring
 
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
Callbacks and control flow in Node js
Thomas Roch
 
You will learn RxJS in 2017
名辰 洪
 
Avoiding Callback Hell with Async.js
cacois
 
Rxjs swetugg
Christoffer Noring
 
Ad

Similar to Reactive Programming Patterns with RxSwift (20)

PDF
Think Async: Asynchronous Patterns in NodeJS
Adam L Barrett
 
PDF
RESTful API using scalaz (3)
Yeshwanth Kumar
 
PPTX
Rx workshop
Ryan Riley
 
PPTX
Rxjs marble-testing
Christoffer Noring
 
PDF
Hw09 Hadoop + Clojure
Cloudera, Inc.
 
PDF
Hadoop + Clojure
elliando dias
 
PDF
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Sages
 
PDF
Reactive programming on Android
Tomáš Kypta
 
PDF
The Evolution of Async-Programming (SD 2.0, JavaScript)
jeffz
 
PDF
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Sages
 
PDF
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
KAI CHU CHUNG
 
ODP
Introduction to Spark with Scala
Himanshu Gupta
 
PPT
JS everywhere 2011
Oleg Podsechin
 
PDF
Swift - One step forward from Obj-C
Nissan Tsafrir
 
PDF
Asynchronous web apps with the Play Framework 2.0
Oscar Renalias
 
PDF
Refactoring to Macros with Clojure
Dmitry Buzdin
 
PDF
Introduction to Scalding and Monoids
Hugo Gävert
 
PDF
Node.js - async for the rest of us.
Mike Brevoort
 
PDF
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
GeeksLab Odessa
 
PDF
Wprowadzenie do technologi Big Data i Apache Hadoop
Sages
 
Think Async: Asynchronous Patterns in NodeJS
Adam L Barrett
 
RESTful API using scalaz (3)
Yeshwanth Kumar
 
Rx workshop
Ryan Riley
 
Rxjs marble-testing
Christoffer Noring
 
Hw09 Hadoop + Clojure
Cloudera, Inc.
 
Hadoop + Clojure
elliando dias
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Sages
 
Reactive programming on Android
Tomáš Kypta
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
jeffz
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Sages
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
KAI CHU CHUNG
 
Introduction to Spark with Scala
Himanshu Gupta
 
JS everywhere 2011
Oleg Podsechin
 
Swift - One step forward from Obj-C
Nissan Tsafrir
 
Asynchronous web apps with the Play Framework 2.0
Oscar Renalias
 
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Introduction to Scalding and Monoids
Hugo Gävert
 
Node.js - async for the rest of us.
Mike Brevoort
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
GeeksLab Odessa
 
Wprowadzenie do technologi Big Data i Apache Hadoop
Sages
 
Ad

Recently uploaded (20)

PDF
Appium Automation Testing Tutorial PDF: Learn Mobile Testing in 7 Days
jamescantor38
 
PPTX
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
PDF
Jenkins: An open-source automation server powering CI/CD Automation
SaikatBasu37
 
PPTX
Presentation about variables and constant.pptx
safalsingh810
 
PDF
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Hironori Washizaki
 
PPTX
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
PDF
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
PDF
The Role of Automation and AI in EHS Management for Data Centers.pdf
TECH EHS Solution
 
PDF
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
PPTX
oapresentation.pptx
mehatdhavalrajubhai
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PDF
Microsoft Teams Essentials; The pricing and the versions_PDF.pdf
Q-Advise
 
PPTX
Explanation about Structures in C language.pptx
Veeral Rathod
 
PPTX
Presentation about variables and constant.pptx
kr2589474
 
PDF
Micromaid: A simple Mermaid-like chart generator for Pharo
ESUG
 
PDF
Exploring AI Agents in Process Industries
amoreira6
 
PPTX
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
PDF
What to consider before purchasing Microsoft 365 Business Premium_PDF.pdf
Q-Advise
 
PDF
Become an Agentblazer Champion Challenge
Dele Amefo
 
PDF
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
Appium Automation Testing Tutorial PDF: Learn Mobile Testing in 7 Days
jamescantor38
 
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
Jenkins: An open-source automation server powering CI/CD Automation
SaikatBasu37
 
Presentation about variables and constant.pptx
safalsingh810
 
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Hironori Washizaki
 
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
The Role of Automation and AI in EHS Management for Data Centers.pdf
TECH EHS Solution
 
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
oapresentation.pptx
mehatdhavalrajubhai
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
Microsoft Teams Essentials; The pricing and the versions_PDF.pdf
Q-Advise
 
Explanation about Structures in C language.pptx
Veeral Rathod
 
Presentation about variables and constant.pptx
kr2589474
 
Micromaid: A simple Mermaid-like chart generator for Pharo
ESUG
 
Exploring AI Agents in Process Industries
amoreira6
 
GALILEO CRS SYSTEM | GALILEO TRAVEL SOFTWARE
philipnathen82
 
What to consider before purchasing Microsoft 365 Business Premium_PDF.pdf
Q-Advise
 
Become an Agentblazer Champion Challenge
Dele Amefo
 
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 

Reactive Programming Patterns with RxSwift

  • 1. Reactive Programming Patterns with RxSwift Florent Pillet — @fpillet FrenchKit Conference Paris — September 23rd, 2016
  • 2. Agenda • Introduction to Rx • Creating observable sequences • Basic patterns • User interface patterns • Architecture patterns
  • 3. About Rx • Microsoft Reactive Extensions (Rx.NET) - 2009 • ReactiveX.io defines a common API for Rx implementations • RxSwift 2015 • Shares concepts and API with other implementations • Heavily tested framework
  • 6. Base concepts • Compose and transform observable sequences using operators • Rx models the asynchronous propagation of change
  • 11. What did we just see? • a sequence emitted one item then completed, • the map operator transformed a sequence of JSON objects into a sequence of Floats, • similar to Swift sequence mapping but asynchronous.
  • 12. What did we just see? Experiment with interactive marble diagrams at rxmarbles.com
  • 13. Observable sequence lifecycle let disposable = someObservable.subscribe( onNext: { print("value: ($0)") }, onCompleted: { print("completed") }, )
  • 14. Observable sequence lifecycle let disposable = someObservable.subscribe( onNext: { print("value: ($0)") }, onError: { print("error ($0)") }, onCompleted: { print("completed") } )
  • 15. Observable sequence lifecycle let disposable = someObservable.subscribe( onNext: { print("value: ($0)") }, onError: { print("error ($0)") }, onCompleted: { print("completed") }, onDisposed: { print("disposed") } ) // at any point, cancel your subscription // by calling dispose() disposable.dispose()
  • 16. The mysterious genesis of the Observable
  • 17. The mysterious genesis of the Observable RxCocoa import RxCocoa let disposable = NSNotificationCenter.defaultCenter() .rx_notification(UIApplicationSignificantTimeChangeNotification) .subscribeNext { (notification: UINotification) in print("Date changed: time to update!") }
  • 18. The mysterious genesis of the Observable RxCocoa import RxCocoa @IBOutlet var textField : UITextField! override func viewDidLoad() { super.viewDidLoad() let _ = textField.rx_text.subscribeNext { (text: String) in print("text field changed to (text)") } }
  • 19. The mysterious genesis of the Observable Manual creation let strings : Observable<Int> = Observable.create { observer in observer.onNext("Hello") observer.onNext("World") observer.onCompleted() // we don't need to release any // resource on dispose() return NopDisposable.instance }
  • 20. The mysterious genesis of the Observable Manual creation let asyncComputation : Observable<Data> = Observable.create { observer in let task = someAsyncTask() task.run( success: { (result: Data) in observer.onNext(result) observer.onCompleted() } error: { (error: ErrorType) in observer.onError(error) } ) return AnonymousDisposable { task.cancel() } }
  • 21. The mysterious genesis of the Observable More ways to obtain observables: • Items from an array or collection • DelegateProxy • rx_observe(type, keypath, options) • rx_sentMessage(#selector) • Subject (stateless) and Variable (stateful)
  • 23. Composition Task: update temperature label when button tapped func getTemperature(city: String) -> Observable<(String,Float)> func formattedTemperature(temp: Float) -> String let disposable = button.rx_tap .withLatestFrom(textField.rx_text) .flatMapLatest { (city: String) -> Observable<(String,Float)> in return getTemperature(city) } .subscribeNext { (temp: (String,Float)) in let degrees = formattedTemperature(temp.1) label.text = "It's (degrees) in (temp.0)" }
  • 24. Aggregation Task: obtain the current temperature in multiple cities let disposable = ["Berlin","London", "Madrid","Paris", "Rome"] .map { (city: String) -> Observable<(String,Float)> in return getTemperature(city) } .toObservable() .merge() .toArray() .subscribeNext { (temperatures: [(String,Float)]) in // we get the result of the five requests // at once in a nice array! }
  • 25. Cancellation Task: update temperature every second until VC disappears var timerDisposable : Disposable! override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) timerDisposable = Observable .timer(0.0, period: 60.0, scheduler: MainScheduler.instance) .flatMap { _ -> Observable<String> in getTemperature("Paris").map { (temp: (String,Float)) -> String in return String(temp.1) } } .bindTo(label.rx_text) } override func viewWillDisappear(animated: Bool) { timerDisposable.dispose() super.viewWillDisappear(animated) }
  • 26. Error handling Task: if a temperature network request fails, display "--" func getTemperatureAsString(city: String) -> Observable<(String,String)> { return getTemperature(city) .map { (temp: (String,Float)) -> String in return (city, formattedTemperature(temp.1)) } .catchErrorJustReturn((city, "--")) }
  • 27. Error handling Task: if a temperature network request fails, display "--" let disposable = button.rx_tap .withLatestFrom(textField.rx_text) .flatMapLatest { (city: String) -> Observable<(String,String)> in return getTemperatureAsString(city) } .map { (temp: (String,String)) -> String in return "It's (temp.1) in (temp.0)" } .bindTo(label.rx_text)
  • 29. Driver let disposable = button.rx_tap .withLatestFrom(textField.rx_text) .flatMapLatest { (city: String) -> Driver<String> in return getTemperature(city) .map { formattedTemperature($0.1) } .asDriver(onErrorJustReturn: "--") } .drive(label.rx_text)
  • 30. Action • not technically part of RxSwift • an important pattern for binding the UI • pod Action • a very useful pattern for MVVM
  • 31. Action import Action lazy var getTemperatureAction : CocoaAction = CocoaAction { [unowned self] in return self.getTemperatureAsString(self.textfield.text) } button.rx_action = getTemperatureAction getTemperatureAction.elements.bindTo(label.rx_text)
  • 33. Architecture patterns • Expose all data to display as Observable sequences • Use Action to wire up the UI whenever possible • MVVM is a perfect fit for Rx
  • 34. Architecture patterns • Decouple application logic from application infrastructure • Storage, geolocation, network requests, image cache etc. are a good fit for insulation • Makes replacing whole parts of the app easier • Testing and mocking are easier too
  • 36. Reactive programming • Powerful way to express program logic • Model the asynchronous propagation of change • Eliminate state from your code • Code is more testable • RxSwift is a solid foundation • Fast growing pool of users, add-ons and contributors (RxSwiftCommunity!)
  • 37. Links • RxSwift source github.com/reactivex/rxswift • Community projects github.com/RxSwiftCommunity • Artsy's Eidolon app github.com/artsy/eidolon • ReactiveX website reactivex.io • RxMarbles rxmarbles.com
  • 38. Q & A