brunch

You can make anything
by writing

C.S.Lewis

by Tilltue Nov 26. 2016

RxCocoa, UIControl extension

RxCocoa, Reactive<Base>, extension

* 이글은 Swift 3.0 , RxSwift 3.0.0, RxCocoa 3.0.0 을 기준으로 작성되었습니다.

RxCocoa  2.0 사용중인 유저를 위한 내용 ( RxCocoa 3.0으로 시작하는 유저는 건너뛰자 )
RxCocoa 3.0 에서, 2.0 에서 쓰이던 rx_tap 에서 rx.tap syntax로 변경되었다.
RxCocoa 의 해당 commit의 비교 내용이다.
Message : " Moves RxCocoa extensions from `rx_` syntax to `rx.` syntax. "
이외에도 Swift api guideline 의 내용을 따라서 바뀐 부분들도 많다.


이번 포스트에서 UIControl을 rx.xxx 형태로 구현하는 예제를 작성하려한다.


UIViewController 에서  viewWillAppear , viewDidAppear ,viewDidDisappear ,viewWillDisappear 를 rx. Observable 형태로 만들어 보자.


RxSwift 3.0 소스 내의 UIViewController+Rx.swift 파일을 보면 다음과 같이 

Reactive 의 확장으로 UIViewController title을 rx.title로 사용할수 있는 코드이다.


extension Reactive where Base: UIViewController {

        /// Bindable sink for `title`.

        public var title: UIBindingObserver<Base, String> {

            return UIBindingObserver(UIElement: self.base) { viewController, title in

                viewController.title = title

            }

        }

    }

또, Reactive.swift  에서는 ReactiveCompatible 프로토콜이 추상화 되어, 이는 곧 UIViewController 에서 rx syntax 를 사용할 수있는 것을 이해할 수 있는 코드이다.

위의 title 처럼 extension Reactive where Base: UIViewController 안에서 자유롭게 확장하면 된다 ~


extension Reactive where Base: UIViewController {

    internal var viewWillAppear: Observable<[Any]> {

        return sentMessage(#selector(UIViewController.viewWillAppear(_:)))

    }

    internal var viewDidAppear: Observable<[Any]> {

        return sentMessage(#selector(UIViewController.viewDidAppear(_:)))

    }

    internal var viewDidDisappear: Observable<[Any]> {

        return sentMessage(#selector(UIViewController.viewDidDisappear(_:)))

    }

    internal var viewWillDisappear: Observable<[Any]> {

        return sentMessage(#selector(UIViewController.viewWillDisappear(_:)))

    }

}


이렇게 rx.viewWillAppear 를 사용할 수 있도록 확장했으며, 사용법은 아래와 같다.

class SomeViewController: UIViewController {

    override func viewDidLoad() {

           super.viewDidLoad()

            rx.viewWillAppear.subscribe(onNext: { _ in

                   print("viewWillAppear")

            }).addDisposableTo(disposeBag)

    }

}


이렇게 간단하게 확장이 가능하다.






브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari