RxSwift

@maxofeden

maxofeden@gmail.com

Called Many Things

  • Lodash/Underscore for Events
  • Promises ++
  • Reactive Programming blah blah

What does it really do?

Helps you manipulate events/callbacks as if they were collections

Handling Events One After the Other

has ALWAYS been a nightmare

Hard Problem?

 

Back to the Basics!

Quiz Time!

let arr = [1,2,3,4,5,6]

Find All Even Numbers?

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

Multiply by 5
all elements?

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

Get the sum
of the array?

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

.reduce(0,+)

Why can't we manipulate events like we do arrays?

Observable<T>
Array<T>

All About that

Observable<T>
pod 'RxSwift'
pod 'RxCocoa'

Observable.just("Hey friend")
    .subscribe{ print($0); }

// "Hey Friend"

How to Create Observables

let array = [1,2,3,4,5,6]

array.toObservable()
    .subscribe{ print($0); }

// "1"
// "2"
// "3"
// "4"
// "5"
// "6"

How to Create Observables #2

rx_someObservable
    .subscribe(onNext: { (emittedValue) in
                print("emittedValue: \(emittedValue)")
            }, onError: { (error) in
                print("error: \(error)")
            }, onCompleted: { 
                print("no more signals")
            })

What's Subscribe?

rx_someObservable
    .subscribe(onNext: { [weak self] (emittedValue) in
                self?.myLabel.text = emittedValue
            }, onError: { (error) in
                self?.myLabel.text = emittedValue
            }, onCompleted: { 
                print("no more signals")
            })

Listener that interacts with

the outside world

let observable = Observable<JSON>( { observer in 
    
    let apiOp = APICall(){ (err, data) in
        if let error = err {
            observer.onError(error)
        } else if let data = data {
            observer.onNext(data);
            observer.onComplete();
        }   
    }

    return AnonymousDisposable {
        apiOp.cancel() //this block runs cancel
    }
})

Fine-Tuned Creation

Remember that Callback Hell?

rx_getMe()
    .flatMap{ me in
        return rx_getMyFriends(me.userId)
    }
    .flatMap{ friends in 
        return rx_getPosts(friends.someId)
    }
    .flatMap{ friends in 
        return rx_getPosts(friends.someId)
    }
    .subscribe(onNext: { allPosts
        print(allPosts)
    })

Chaining Events

Zipping Observables

Observable.zip(rx_A, rx_B){
    return rx_A == rx_B
}.subscribeNext{ print(isTrue) }

Zipping

Combining Observables

Observable.combineLatest(rx_A, rx_B){
    return rx_A == rx_B
}.subscribeNext{ print(isTrue) }

Combining

 

Merging

[rx_A, rx_B].toObservable().merge()
    .subscribeNext{ print("either: \($0)") }

Merging

RxCocoa

Operator Extensions for UIKit

override func viewDidLoad() {
    super.viewDidLoad();

    button.addTarget(self, 
        action: #selector(ViewController.tappedButton), 
        forControlEvents: .TouchUpInside)
}

func tappedButton(sender: AnyObject){
    print("TAPPED_BUTTON")
}

Vanilla UIKit for Button Tap

override func viewDidLoad() {
    super.viewDidLoad();
    button.rx_tap.subscribeNext {
        print("TAPPED_BUTTON")
    }
}

Now with RxSwift

Made with Slides.com