rxswift 예제로 감잡기

31
RxSwift 예제로 감잡기 RxSwift 시작을 위한 간단한 예제들 유용하 @inkyfox github.com/inkyfox

Upload: yong-ha-yoo

Post on 12-Apr-2017

108 views

Category:

Software


5 download

TRANSCRIPT

Page 1: RxSwift 예제로 감잡기

RxSwift�예제로�감잡기RxSwift�시작을�위한�간단한�예제들�

유용하�@inkyfox�

github.com/inkyfox

Page 2: RxSwift 예제로 감잡기

ReactiveX

•왜�쓰는가?�

•장점?�

•설치는?�

•비동기..�함수형..�LINQ..�MVVM..?��

• Observable?�Observer?

Page 3: RxSwift 예제로 감잡기

ReactiveX

•왜�쓰는가?�

•장점?�

•설치는?�

•비동기..�함수형..�LINQ..�MVVM..?��

• Observable?�Observer?

일단�생략

Page 4: RxSwift 예제로 감잡기

ReactiveX

먼저�코드�예제를�보며�감을�잡아�보는�걸로

Page 5: RxSwift 예제로 감잡기

UI Eventfunc reload() { }

func setup() { reloadButton.rx.tap // Observable<Void> .subscribe(onNext: { [weak self] in self?.reload() }) .addDisposableTo(disposeBag) }

Page 6: RxSwift 예제로 감잡기

UI Eventfunc reload() { }

func setup() { reloadButton.rx.tap // Observable<Void> .subscribe(onNext: { [weak self] in self?.reload() }) .addDisposableTo(disposeBag) }

Page 7: RxSwift 예제로 감잡기

UI Eventfunc reload() { }

func setup() { reloadButton.rx.tap // Observable<Void> .bindNext(reload) .addDisposableTo(disposeBag) }

Page 8: RxSwift 예제로 감잡기

UI Eventfunc reload() { }

func setup() { reloadButton.rx.tap // Observable<Void> .do(onNext: { print(“Reload Button Clicked.”) Analytics.buttonReload.send() }) .bindNext(reload) .addDisposableTo(disposeBag) }

Page 9: RxSwift 예제로 감잡기

UI Eventfunc reload() { }

func setup() { reloadButton.rx.tap // Observable<Void> .debounce(0.3, scheduler: MainScheduler.instance) .do(onNext: { print(“Reload Button Clicked.”) Analytics.buttonReload.send() }) .bindNext(reload) .addDisposableTo(disposeBag) }

Page 10: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .map { json in Page(json: json) } // Observable<Page> .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] page in self?.display(page: page) }) .addDisposableTo(reloadDisposeBag) }

func display(page: Page) { }

Page 11: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .map { json in Page(json: json) } // Observable<Page> .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] page in self?.display(page: page) }) .addDisposableTo(reloadDisposeBag) }

func display(page: Page) { }

Page 12: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .map { json in Page(json: json) } // Observable<Page> .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] page in self?.display(page: page) }) .addDisposableTo(reloadDisposeBag) }

func display(page: Page) { }

Page 13: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .map { json in Page(json: json) } // Observable<Page> .observeOn(MainScheduler.instance) .bindNext(display) .addDisposableTo(reloadDisposeBag) }

func display(page: Page) { }

Page 14: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .map { Page(json: $0) } // Observable<Page> .observeOn(MainScheduler.instance) .bindNext(display) .addDisposableTo(reloadDisposeBag) }

func display(page: Page) { }

Page 15: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .retry(2) .map { Page(json: $0) } // Observable<Page> .observeOn(MainScheduler.instance) .bindNext(display) .addDisposableTo(reloadDisposeBag) }

func display(page: Page) { }

Page 16: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .subscribeOn(SerialDispatchQueueScheduler(qos: .background)) .retry(2) .observeOn(ConcurrentDispatchQueueScheduler(qos: .background)) .map(Page.init) // Observable<Page> .observeOn(MainScheduler.instance) .bindNext(display) .addDisposableTo(reloadDisposeBag) }

func display(page: Page) { }

Page 17: RxSwift 예제로 감잡기

REST APIfunc reload() { API.default.request(.getPage) // Observable<JSON> .subscribeOn(SerialDispatchQueueScheduler(qos: .background)) .retry(2) .observeOn(ConcurrentDispatchQueueScheduler(qos: .background)) .map(Page.init) // Observable<Page> .observeOn(MainScheduler.instance) .do( onNext: { print("Reload success: \($0)") }, onError: { error in print("Reload failed! \(error)") }, onCompleted: { print("Reload completed") } ) .bindNext(display) .addDisposableTo(reloadDisposeBag) }

Page 18: RxSwift 예제로 감잡기

Property Binding let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] reloading in self?.reloadButton.isEnabled = !reloading }) .addDisposableTo(disposeBag) }

Page 19: RxSwift 예제로 감잡기

Property Binding let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] reloading in self?.reloadButton.isEnabled = !reloading }) .addDisposableTo(disposeBag) }

Page 20: RxSwift 예제로 감잡기

Property Binding let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .map { !$0 } .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] enabled in self?.reloadButton.isEnabled = enabled }) .addDisposableTo(disposeBag) }

Page 21: RxSwift 예제로 감잡기

Property Binding let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .map { !$0 } .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] enabled in self?.reloadButton.isEnabled = enabled }) .addDisposableTo(disposeBag) }

Page 22: RxSwift 예제로 감잡기

Property Binding let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .map { !$0 } .observeOn(MainScheduler.instance) .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) }

Page 23: RxSwift 예제로 감잡기

Merge Operator let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .map { !$0 } .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) reloadButton.rx.tap // Observable<Void> .map { false } // Observable<Bool> .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) }

Page 24: RxSwift 예제로 감잡기

Merge Operator let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .map { !$0 } .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) reloadButton.rx.tap // Observable<Void> .map { false } // Observable<Bool> .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) }

Page 25: RxSwift 예제로 감잡기

Merge Operator let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // Observable<Bool> .map { !$0 } .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) reloadButton.rx.tap // Observable<Void> .map { false } // Observable<Bool> .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) }

Page 26: RxSwift 예제로 감잡기

Merge Operator let isReloading: Variable<Bool> = Variable(false)

func setup() { Observable.from( [isReloading.asObservable().map { !$0 }, reloadButton.rx.tap.map { false } ] ).merge() // Observable<Bool> .bindTo(reloadButton.rx.isEnabled) .addDisposableTo(disposeBag) }

Page 27: RxSwift 예제로 감잡기

Operators let isReloading: Variable<Bool> = Variable(false)

func setup() { isReloading.asObservable() // |-F-T-F-T-F- .filter { $0 == false } // |-F---F---F- .skip(1) // |-----F---F- .take(1) // |-----F| .observeOn(MainScheduler.instance) .bindTo(messageView.rx.isHidden) .addDisposableTo(disposeBag) }

Page 28: RxSwift 예제로 감잡기

그�밖에

•NotificationCenter�

• Animation�

•등의�모든�이벤트�

• 예제:�https://github.com/inkyfox/RxCurrency_iOS

Page 29: RxSwift 예제로 감잡기

ReactiveX

• Pulling이�아닌�Pushing�Data�(수동적)�

• LINQ�style�연산자�&�함수형�프로그래밍�

•비동기�(Async)�프로그래밍

Page 30: RxSwift 예제로 감잡기

ReactiveX

앞의�예제들을�

�Callback�(Delegate�pattern)으로�했으면�

�어땠을까�상상해봅시다

Page 31: RxSwift 예제로 감잡기

공부

• http://www.introtorx.com

• http://reactivex.io/intro.html

• http://rxmarbles.com

• https://github.com/ReactiveX/RxSwift/tree/master/Documentation