reactive programming with rxswift
Post on 16-Apr-2017
930 Views
Preview:
TRANSCRIPT
RXSWIFTREACTIVE PROGRAMMING WITH
WHO AM I?
▸ iOS developer since 2010
▸ Swift since day 1
▸ Transitioning to Swift
▸ CocoaConf
▸ Wash U
▸ RayWenderlich.com
▸ lynda.com
WHO ARE YOU?
▸ iOS developer
▸ How long?
▸ Swift developer
▸ How long?
▸ Reactive programming
▸ ReactiveCocoa
▸ Reactive Extensions
WHAT IS REACTIVE PROGRAMMING?
REACTVE PROGRAMMING IS ESSENTIALLY WORKING WITH ASYNCHRONOUS DATA STREAMS
@fpillet
ABOUT REACTIVE EXTENSIONS
▸ Event-driven
▸ Asynchronous
▸ Functional
▸ Common patterns
▸ Observer
▸ Iterator
▸ Cross-platform
CANONICAL EXAMPLE
IMPERATIVE
a = 3 b = 4 c = a + b // 7 a = 6 c // 7
CANONICAL EXAMPLE
REACTIVE
a = 3 b = 4 c = a + b a = 6 c // 10
// 7
TRADITIONAL VS. REACTIVEA SIMPLE EXAMPLE IN IOS
MODEL
VIEW MODEL
VIEW CONTROLLER
REACTIVE VIEW MODEL
REACTIVE VIEW CONTROLLER
THE RESULTS
40% LESS
Environment
Interactive
Reactive
Program
REACTIVE EXTENSIONS
Nov. ‘09
Rx.NET
RxJS
Mar. ‘10
RxJava
Mar. ‘12
RxCpp
Nov. ‘12
RxRuby
Dec. ‘12
RxSca
la, RxC
lojure, RxG
roovy, RxJR
uby
Jan. ‘1
3
RxPY, R
xPHP
Mar. ‘13
RxKotlin
Oct. ‘1
3
RxSwift
Feb. ‘1
5
REACTIVE MANIFESTO
RX STANDARDIZES THE PATTERNS & OPERATORS USED TO DEVELOP ASYNCHRONOUS APPS IN MULTIPLE ENVIRONMENTS.
RXSWIFT OPERATORS
▸ Creating
asObservable
create
deferred
empty
error
toObservable
interval
never
just
of
range
repeatElement
timer
▸ Transforming
buffer
flatMap
flatMapFirst
flatMapLatest
map
scan
window
▸ Filtering
debounce / throttle
distinctUntilChanged
elementAt
filter
sample
skip
take
takeLast
single
▸ Conditional & Boolean
amb
skipWhile
skipUntil
takeUntil
takeWhile
▸ Mathematical & Aggregate
concat
reduce
toArray
▸ Connectable
multicast
publish
refCount
replay
shareReplay
▸ Combining
merge
startWith
switchLatest
combineLatest
zip
▸ Error Handling
catch
retry
retryWhen
▸ Observing
delaySubscription
do / doOnNext
observeOn
subscribe
subscribeOn
timeout
using
debug
LIFECYCLE OF AN OBSERVABLE (AKA SEQUENCE)
▸ onNext
▸ onError
▸ onComplete
▸ dispose() / DisposeBag
DO YOU HAZ TEH CODEZ ?!?
SETUP
▸ Install ThisCouldBeUsButYouPlaying
▸ bit.ly/podsPlaygrounds
▸ gem install cocoapods-playgrounds
▸ Create RxSwiftPlayground
▸ pod playgrounds RxSwift
SETUP
//: Please build the scheme 'RxSwiftPlayground' first import XCPlayground XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
import RxSwift
SETUP
//: Please build the scheme 'RxSwiftPlayground' first import XCPlayground XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
import RxSwift
func exampleOf(description: String, action: Void -> Void) { print("\n--- Example of:", description, "---") action() }
--- Example of: just --- Next(32) Completed
exampleOf("just") {
Observable.just(32) .subscribe {
print($0)
}
}
CREATING & SUBSCRIBING
--- Example of: just --- Next(32) Completed
exampleOf("just") {
Observable.just(32) .subscribe { value in
print(value)
}
}
CREATING & SUBSCRIBING
--- Example of: just --- 32
exampleOf("just") {
_ = Observable.just(32).subscribeNext { print($0) }
}
CREATING & SUBSCRIBING
--- Example of: of --- 1 2 3 4 5
exampleOf("of") {
Observable.of(1, 2, 3, 4, 5) .subscribeNext { print($0) } .dispose()
}
CREATING & SUBSCRIBING
--- Example of: toObservable --- 1 2 3
exampleOf("toObservable") { let disposeBag = DisposeBag() [1, 2, 3].toObservable() .subscribeNext { print($0) } .addDisposableTo(disposeBag) }
CREATING & SUBSCRIBING
--- Example of: BehaviorSubject --- Next(Hello) Next(World!)
exampleOf("BehaviorSubject") { let disposeBag = DisposeBag() let string = BehaviorSubject(value: "Hello") string.subscribe { print($0) } .addDisposableTo(disposeBag) string.onNext("World!") }
CREATING & SUBSCRIBING
CREATING & SUBSCRIBING
--- Example of: Variable --- Next(1) Next(12) Next(1234567) Completed
exampleOf("Variable") { let disposeBag = DisposeBag() let number = Variable(1) number.asObservable() .subscribe { print($0) } .addDisposableTo(disposeBag) number.value = 12 number.value = 1_234_567 }
exampleOf("map") { Observable.of(1, 2, 3) .map { $0 * $0 } .subscribeNext { print($0) } .dispose() }
TRANSFORMING
--- Example of: map --- 1 4 9
TRANSFORMING
--- Example of: Variable and map --- one twelve one million two hundred thirty-four thousand five hundred sixty-seven
exampleOf("Variable and map") { let disposeBag = DisposeBag() let numberFormatter = NSNumberFormatter() numberFormatter.numberStyle = .SpellOutStyle let number = Variable(1) number.asObservable() .map { numberFormatter.stringFromNumber($0)! } .subscribeNext { print($0) } .addDisposableTo(disposeBag) number.value = 12 number.value = 1_234_567 }
TRANSFORMING
--- Example of: flatMap --- Scott Lori Eric
exampleOf("flatMap") { let disposeBag = DisposeBag() struct Person { var name: Variable<String> } let scott = Person(name: Variable("Scott")) let lori = Person(name: Variable("Lori")) let person = Variable(scott) person.asObservable() .flatMap { $0.name.asObservable() } .subscribeNext { print($0) } .addDisposableTo(disposeBag) person.value = lori scott.name.value = "Eric" }
TRANSFORMING
--- Example of: flatMapLatest --- Scott Lori
exampleOf("flatMap") { let disposeBag = DisposeBag() struct Person { var name: Variable<String> } let scott = Person(name: Variable("Scott")) let lori = Person(name: Variable("Lori")) let person = Variable(scott) person.asObservable() .flatMapLatest { $0.name.asObservable() } .subscribeNext { print($0) } .addDisposableTo(disposeBag) person.value = lori scott.name.value = "Eric" }
exampleOf("distinctUntilChanged") { let disposeBag = DisposeBag() let searchString = Variable("iOS") searchString.asObservable() .map { $0.lowercaseString } .distinctUntilChanged() .subscribeNext { print($0) } .addDisposableTo(disposeBag) searchString.value = "IOS" searchString.value = "Rx" searchString.value = "ios" }
FILTERING
--- Example of: distinctUntilChanged --- ios rx ios
exampleOf("combineLatest") { let disposeBag = DisposeBag() let number = PublishSubject<Int>() let string = PublishSubject<String>() Observable.combineLatest(number, string) { "\($0) \($1)" } .subscribeNext { print($0) } .addDisposableTo(disposeBag) number.onNext(1) print("Nothing yet") string.on(.Next("A")) number.onNext(2) string.onNext("B") string.onNext("C") }
COMBINING
--- Example of: combineLatest --- Nothing yet 1 A 2 A 2 B 2 C
exampleOf("takeWhile") { [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1].toObservable() .takeWhile { $0 < 5 } .subscribeNext { print($0) } .dispose() }
CONDITIONAL
--- Example of: takeWhile --- 1 2 3 4
MATHEMATICAL
--- Example of: reduce --- 1024
exampleOf("reduce") { [1, 2, 4, 8, 16].toObservable() .reduce(1, accumulator: *) .subscribeNext { print($0) } .dispose() }
ERROR HANDLING
--- Example of: error --- A
exampleOf("error") { enum Error: ErrorType { case A } Observable<Int>.error(Error.A) .subscribeError { // Handle error print($0) } .dispose() }
RXMARBLES
RXSWIFTPLAYER
OBJECTIONS
1. Dependency
2. Complexity
3. Performance
4. Debugging
5. Help
BENEFITS
1. Write less, do more
2. Avoid mutable state errors
3. Learn once, apply everywhere
4. Mix in or go all in
5. “It reads almost like a paragraph”
6. Easy to test and heavily tested
QUESTIONS?
WANT MORE RX?
▸ github.com/ReactiveX/RxSwift
▸ reactivex.io
▸ rxmarbles.com
▸ rxswift.slack.com
▸ rx-marin.com
▸ http://as.ync.io
▸ github.com/scotteg/RxSwiftPlayer
▸ github.com/Artsy/eidolon
THANK YOU!
Scott Gardner @scotteg as.ync.io bit.ly/scottOnLyndaDotCom
top related