rxswift 예제로 감잡기
TRANSCRIPT
RxSwift�예제로�감잡기RxSwift�시작을�위한�간단한�예제들�
유용하�@inkyfox�
github.com/inkyfox
ReactiveX
•왜�쓰는가?�
•장점?�
•설치는?�
•비동기..�함수형..�LINQ..�MVVM..?��
• Observable?�Observer?
ReactiveX
•왜�쓰는가?�
•장점?�
•설치는?�
•비동기..�함수형..�LINQ..�MVVM..?��
• Observable?�Observer?
일단�생략
ReactiveX
먼저�코드�예제를�보며�감을�잡아�보는�걸로
UI Eventfunc reload() { }
func setup() { reloadButton.rx.tap // Observable<Void> .subscribe(onNext: { [weak self] in self?.reload() }) .addDisposableTo(disposeBag) }
UI Eventfunc reload() { }
func setup() { reloadButton.rx.tap // Observable<Void> .subscribe(onNext: { [weak self] in self?.reload() }) .addDisposableTo(disposeBag) }
UI Eventfunc reload() { }
func setup() { reloadButton.rx.tap // Observable<Void> .bindNext(reload) .addDisposableTo(disposeBag) }
UI Eventfunc reload() { }
func setup() { reloadButton.rx.tap // Observable<Void> .do(onNext: { print(“Reload Button Clicked.”) Analytics.buttonReload.send() }) .bindNext(reload) .addDisposableTo(disposeBag) }
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) }
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) { }
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) { }
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) { }
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) { }
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) { }
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) { }
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) { }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
그�밖에
•NotificationCenter�
• Animation�
•등의�모든�이벤트�
• 예제:�https://github.com/inkyfox/RxCurrency_iOS
ReactiveX
• Pulling이�아닌�Pushing�Data�(수동적)�
• LINQ�style�연산자�&�함수형�프로그래밍�
•비동기�(Async)�프로그래밍
ReactiveX
앞의�예제들을�
�Callback�(Delegate�pattern)으로�했으면�
�어땠을까�상상해봅시다
공부
• http://www.introtorx.com
• http://reactivex.io/intro.html
• http://rxmarbles.com
• https://github.com/ReactiveX/RxSwift/tree/master/Documentation