Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Reactive Programming with RxSwift

1fa9cb8c7997c8c4d3d251fb5e41f749?s=47 Realm
December 03, 2015

Functional Reactive Programming with RxSwift

Presented by Max Alexander at the Swift Language User Group on 12.03.15

1fa9cb8c7997c8c4d3d251fb5e41f749?s=128

Realm

December 03, 2015
Tweet

Transcript

  1. RxSwift Maximilian Alexander mbalex99@gmail.com

  2. 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: { }) })
  3. You can’t solve problems with the same thinking that caused

    them. Albert Einstein
  4. Go back to the basics to solve hairy problems

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

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

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

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

  9. I/O Async Events

  10. We the people have the right to manipulate async events

    just like iterable collections Rx Bill of Rights
  11. Instead of Array Values, Can we do this with Events?

  12. Observable<T> Array<T>

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

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

  15. create { (observer: AnyObserver<AuthResponse>) -> Disposable in return AnonymousDisposable {

    } } Creation - Fine Tuned Control
  16. Creation - Fine Tuned Control create { (observer: AnyObserver<AuthResponse>) ->

    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() }
  17. Subscribing for Data [1,2,3,4,5,6] .toObservable() .subscribeNext { print($0) } “1”

    “2” “3” “4” “5” “6”
  18. 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 }
  19. B A C D E 1 2 3 4 5

    What about multiple observable streams?
  20. 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
  21. Combining Observables func rx_canBuy() -> Observable<Bool> { let stockPulse :

    [Observable<StockPulse>] let accountBalance : Observable<Double> return combineLatest(stockPulse, accountBalance, resultSelector: { (pulse, bal) -> Bool in return pulse.price < bal }) }
  22. Making It Meaningful rx_canBuy() .subscribeNext { (canBuy) -> Void in

    self.buyButton.enabled = canBuy }
  23. Merge let myFavoriteStocks : [Observable<StockPulse>] myFavoriteStocks.merge() .subscribeNext { (stockPulse) ->

    Void in print(“\(stockPulse.symbol)/ updated to \(stockPulse.price)/”) }
  24. http://rxmarbles.com/

  25. 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 }
  26. This is just the surface of RxSwift

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

  28. Powerful MVVM with RxCocoa

  29. Powerful MVVM with RxCocoa Just a Teaser

  30. Interested in Cross Platform -ish?

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

  32. func rx_login(username: String, password: String) -> Observable<Any> { 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() } }) }
  33. fun rx_login(username: String, password: String): Observable<JSONObject> {
 return Observable.create ({

    subscriber ->
 val body = JSONObject()
 body.put("username", username)
 body.put("password", password)
 val listener = Response.Listener<JSONObject>({ 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)
 });
 }
  34. rx_login = (username: string, password: string) : Observable<any> => {


    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()
 }
 });
 }
  35. Thanks! Questions?