Slide 1

Slide 1 text

RxSwift Maximilian Alexander [email protected]

Slide 2

Slide 2 text

Alamofire.request(.POST, "login", parameters: ["username": "max", "password": "insanity"]) .responseJSON(completionHandler: { (firedResponse) -> Void in Alamofire.request(.GET, "myUserInfo" + firedResponse.result.value) .responseJSON(completionHandler: { myUserInfoResponse in Alamofire.request(.GET, "friendList" + myUserInfoResponse.result.value) .responseJSON(completionHandler: { friendListResponse in Alamofire.request(.GET, "blockedUsers" + friendListResponse.result.value) .responseJSON(completionHandler: { }) }) }) Alamofire.request(.GET, "myUserAcccount" + firedResponse.result.value) .responseJSON(completionHandler: { }) })

Slide 3

Slide 3 text

You can’t solve problems with the same thinking that caused them. Albert Einstein

Slide 4

Slide 4 text

Go back to the basics to solve hairy problems

Slide 5

Slide 5 text

[1, 2, 3, 4, 5, 6]

Slide 6

Slide 6 text

[1, 2, 3, 4, 5, 6] .filter{ $0 % 2 == 0 }

Slide 7

Slide 7 text

[1, 2, 3, 4, 5, 6] .map{ $0 * 5 }

Slide 8

Slide 8 text

[1, 2, 3, 4, 5, 6] .reduce(0, +)

Slide 9

Slide 9 text

I/O Async Events

Slide 10

Slide 10 text

We the people have the right to manipulate async events just like iterable collections Rx Bill of Rights

Slide 11

Slide 11 text

Instead of Array Values, Can we do this with Events?

Slide 12

Slide 12 text

Observable Array

Slide 13

Slide 13 text

pod 'RxSwift', '~> 2.0.0-beta.3' import RxSwift

Slide 14

Slide 14 text

Creation - Simplest Form just(1) [1,2,3,4,5,6] .toObservable() Observable Observable

Slide 15

Slide 15 text

create { (observer: AnyObserver) -> Disposable in return AnonymousDisposable { } } Creation - Fine Tuned Control

Slide 16

Slide 16 text

Creation - Fine Tuned Control create { (observer: AnyObserver) -> Disposable in let request = MyAPI.get(url, ( (result, error) -> { if let err = error { observer.onError(err); } else if let authResponse = result { observer.onNext(authResponse); observer.onComplete(); } }) return AnonymousDisposable { request.cancel() }

Slide 17

Slide 17 text

Subscribing for Data [1,2,3,4,5,6] .toObservable() .subscribeNext { print($0) } “1” “2” “3” “4” “5” “6”

Slide 18

Slide 18 text

Subscribing for Data, Error, And Completion [1,2,3,4,5,6] .toObservable() .subscribe(onNext: { (intValue) -> Void in // Pumped out an int }, onError: { (error) -> Void in // ERROR! }, onCompleted: { () -> Void in // There are no more signals }) { () -> Void in // We disposed this subscription }

Slide 19

Slide 19 text

B A C D E 1 2 3 4 5 What about multiple observable streams?

Slide 20

Slide 20 text

Sequential API Calls 1. Get the UserId 2. Get his Stripe Credit Card Account Id 3. Get his Credit Card Tokens 4. Delete his Expired Cards 5. Send Email of the Cards that Were Successfully Deleted

Slide 21

Slide 21 text

Combining Observables func rx_canBuy() -> Observable { let stockPulse : [Observable] let accountBalance : Observable return combineLatest(stockPulse, accountBalance, resultSelector: { (pulse, bal) -> Bool in return pulse.price < bal }) }

Slide 22

Slide 22 text

Making It Meaningful rx_canBuy() .subscribeNext { (canBuy) -> Void in self.buyButton.enabled = canBuy }

Slide 23

Slide 23 text

Merge let myFavoriteStocks : [Observable] myFavoriteStocks.merge() .subscribeNext { (stockPulse) -> Void in print(“\(stockPulse.symbol)/ updated to \(stockPulse.price)/”) }

Slide 24

Slide 24 text

http://rxmarbles.com/

Slide 25

Slide 25 text

Background Processes with Ease let operationQueue = NSOperationQueue() operationQueue.maxConcurrentOperationCount = 3 operationQueue.qualityOfService = NSQualityOfService.UserInitiated let backgroundWorkScheduler = OperationQueueScheduler(operationQueue: operationQueue) videoUpload .observeOn(backgroundWorkScheduler) .map({ json in return json["videoUrl"].stringValue }) .observeOn(MainScheduler.sharedInstance) .subscribeNext{ url self.urlLabel.text = url }

Slide 26

Slide 26 text

This is just the surface of RxSwift

Slide 27

Slide 27 text

pod 'RxCocoa', '~> 2.0.0-beta.3' import RxSwift import RxCocoa

Slide 28

Slide 28 text

Powerful MVVM with RxCocoa

Slide 29

Slide 29 text

Powerful MVVM with RxCocoa Just a Teaser

Slide 30

Slide 30 text

Interested in Cross Platform -ish?

Slide 31

Slide 31 text

Kotlin - RxJava (RxKotlin) TypeScript - RxJS Swift - RxSwift

Slide 32

Slide 32 text

func rx_login(username: String, password: String) -> Observable { return create({ (observer) -> Disposable in let postBody = [ "username": username, "password": password ] let request = Alamofire.request(.POST, "login", parameters: postBody) .responseJSON(completionHandler: { (firedResponse) -> Void in if let value = firedResponse.result.value { observer.onNext(value) observer.onCompleted() } else if let error = firedResponse.result.error { observer.onError(error) } }) return AnonymousDisposable{ request.cancel() } }) }

Slide 33

Slide 33 text

fun rx_login(username: String, password: String): Observable {
 return Observable.create ({ subscriber ->
 val body = JSONObject()
 body.put("username", username)
 body.put("password", password)
 val listener = Response.Listener({ response ->
 subscriber.onNext(response);
 subscriber.onCompleted()
 })
 val errListener = Response.ErrorListener { err ->
 subscriber.onError(err)
 }
 val request = JsonObjectRequest(Request.Method.POST, "login", listener, errList this.requestQueue.add(request)
 });
 }

Slide 34

Slide 34 text

rx_login = (username: string, password: string) : Observable => {
 return Observable.create(observer => {
 let body = {
 username: username,
 password: password
 };
 let request = $.ajax({
 method: 'POST',
 url: url,
 data: body,
 error: (err) => {
 observer.onError(err);
 },
 success: (data) => {
 observer.onNext(data);
 observer.onCompleted();
 }
 });
 return () => {
 request.abort()
 }
 });
 }

Slide 35

Slide 35 text

Thanks! Questions?