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
PDF
Reactive Programming with RxSwift
PDF
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
PDF
Functional Reactive Programming - RxSwift
PDF
Cascadia.js: Don't Cross the Streams
PDF
Swift Sequences & Collections
PDF
Angular and The Case for RxJS
PDF
Reactive, component 그리고 angular2
Reactive programming with RxSwift
Reactive Programming with RxSwift
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Functional Reactive Programming - RxSwift
Cascadia.js: Don't Cross the Streams
Swift Sequences & Collections
Angular and The Case for RxJS
Reactive, component 그리고 angular2

What's hot (20)

PPTX
PDF
Introduction to RxJS
PDF
Map kit light
PDF
Oop assignment 02
PDF
Understanding Asynchronous JavaScript
PPTX
Rxjs ngvikings
PDF
Introduction to reactive programming & ReactiveCocoa
PPTX
Luis Atencio on RxJS
PDF
RxJS Evolved
PDF
RxJS 5 in Depth
PDF
Intro to RxJava/RxAndroid - GDG Munich Android
PDF
Realm.io par Clement Sauvage
PDF
RxJS101 - What you need to know to get started with RxJS tomorrow
PDF
RxJS - The Reactive extensions for JavaScript
PPTX
Angular2 rxjs
PPTX
Functional Reactive Programming (FRP): Working with RxJS
PDF
Callbacks and control flow in Node js
PDF
You will learn RxJS in 2017
PPTX
Avoiding Callback Hell with Async.js
PPTX
Rxjs swetugg
Introduction to RxJS
Map kit light
Oop assignment 02
Understanding Asynchronous JavaScript
Rxjs ngvikings
Introduction to reactive programming & ReactiveCocoa
Luis Atencio on RxJS
RxJS Evolved
RxJS 5 in Depth
Intro to RxJava/RxAndroid - GDG Munich Android
Realm.io par Clement Sauvage
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS - The Reactive extensions for JavaScript
Angular2 rxjs
Functional Reactive Programming (FRP): Working with RxJS
Callbacks and control flow in Node js
You will learn RxJS in 2017
Avoiding Callback Hell with Async.js
Rxjs swetugg
Ad

Similar to Reactive Programming Patterns with RxSwift (20)

PDF
Think Async: Asynchronous Patterns in NodeJS
PDF
RESTful API using scalaz (3)
PPTX
Rx workshop
PPTX
Rxjs marble-testing
PDF
Hw09 Hadoop + Clojure
PDF
Hadoop + Clojure
PDF
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
PDF
Reactive programming on Android
PDF
The Evolution of Async-Programming (SD 2.0, JavaScript)
PDF
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
PDF
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
ODP
Introduction to Spark with Scala
PPT
JS everywhere 2011
PDF
Swift - One step forward from Obj-C
PDF
Asynchronous web apps with the Play Framework 2.0
PDF
Refactoring to Macros with Clojure
PDF
Introduction to Scalding and Monoids
PDF
Node.js - async for the rest of us.
PDF
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
PDF
Wprowadzenie do technologi Big Data i Apache Hadoop
Think Async: Asynchronous Patterns in NodeJS
RESTful API using scalaz (3)
Rx workshop
Rxjs marble-testing
Hw09 Hadoop + Clojure
Hadoop + Clojure
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Reactive programming on Android
The Evolution of Async-Programming (SD 2.0, JavaScript)
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
Introduction to Spark with Scala
JS everywhere 2011
Swift - One step forward from Obj-C
Asynchronous web apps with the Play Framework 2.0
Refactoring to Macros with Clojure
Introduction to Scalding and Monoids
Node.js - async for the rest of us.
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Wprowadzenie do technologi Big Data i Apache Hadoop
Ad

Recently uploaded (20)

PDF
iTop VPN Crack Latest Version Full Key 2025
PDF
Website Design Services for Small Businesses.pdf
PDF
DNT Brochure 2025 – ISV Solutions @ D365
PDF
Cost to Outsource Software Development in 2025
PDF
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
PDF
Ableton Live Suite for MacOS Crack Full Download (Latest 2025)
PPTX
Cybersecurity: Protecting the Digital World
DOCX
How to Use SharePoint as an ISO-Compliant Document Management System
PPTX
CNN LeNet5 Architecture: Neural Networks
PDF
MCP Security Tutorial - Beginner to Advanced
PDF
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
PDF
Visual explanation of Dijkstra's Algorithm using Python
PDF
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
PPTX
GSA Content Generator Crack (2025 Latest)
PDF
Topaz Photo AI Crack New Download (Latest 2025)
PPTX
Monitoring Stack: Grafana, Loki & Promtail
PDF
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
PDF
CCleaner 6.39.11548 Crack 2025 License Key
PPTX
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
PDF
Microsoft Office 365 Crack Download Free
iTop VPN Crack Latest Version Full Key 2025
Website Design Services for Small Businesses.pdf
DNT Brochure 2025 – ISV Solutions @ D365
Cost to Outsource Software Development in 2025
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
Ableton Live Suite for MacOS Crack Full Download (Latest 2025)
Cybersecurity: Protecting the Digital World
How to Use SharePoint as an ISO-Compliant Document Management System
CNN LeNet5 Architecture: Neural Networks
MCP Security Tutorial - Beginner to Advanced
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
Visual explanation of Dijkstra's Algorithm using Python
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
GSA Content Generator Crack (2025 Latest)
Topaz Photo AI Crack New Download (Latest 2025)
Monitoring Stack: Grafana, Loki & Promtail
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
CCleaner 6.39.11548 Crack 2025 License Key
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
Microsoft Office 365 Crack Download Free

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