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)
}
}
이렇게 간단하게 확장이 가능하다.