RxSwift 라이브러리에서 Reactive.swift 안에 코드와 주석을 보면,
아래와 같이 Base에 특정 타입을 지정해서 Reactive를 확장해서 사용하라고 되어있습니다.
@dynamicMemberLookup
public struct Reactive<Base> {
/// Base object to extend.
public let base: Base
/// Creates extensions with base object.
///
/// - parameter base: Base object.
public init(_ base: Base) {
self.base = base
}
/// Automatically synthesized binder for a key path between the reactive
/// base and one of its properties
public subscript<Property>(dynamicMember keyPath: ReferenceWritableKeyPath<Base, Property>) -> Binder<Property> where Base: AnyObject {
Binder(self.base) { base, value in
base[keyPath: keyPath] = value
}
}
}
일반적인 패턴은 아래와 같습니다.
extension Reactive where Base: SomeType { }
func bind(viewModel: LocationInfoViewModel) {
viewModel.setMapCenter
.emit(to: mapView.rx.setMapCenterPoint)
.disposed(by: disposeBag)
viewModel.errorMessage
.emit(to: self.rx.presentAlert)
.disposed(by: disposeBag)
currentLocattionButton.rx.tap
.bind(to: viewModel.didTappedCurrentLocationBtn)
.disposed(by: disposeBag)
}
extension Reactive where Base: LocationInfoViewController {
var presentAlert: Binder<String> {
return Binder(base) { base, message in
let alertController = UIAlertController(
title: "문제 발생",
message: message,
preferredStyle: .alert)
let action = UIAlertAction(
title: "확인",
style: .default)
alertController.addAction(action)
base.present(alertController, animated: true)
}
}
}
Alert을 present를 할 때 message를 관찰할 필요 없이 값을 주입시키면 되기 때문에 Binder를 사용하는 게 맞습니다.
https://zeddios.tistory.com/1250
https://thoonk.tistory.com/92
https://cheonsong.tistory.com/23#2.%20Binder%20구현