매거진 ReactiveX

You can make anything
by writing

C.S.Lewis

by Tilltue Oct 26. 2016

RxSwift, 이지벳 와 Observable

이지벳Proxy,이지벳ProxyType

이지벳

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

Swift 에서 일반적인 이지벳 / protocol 를 사용하는 구조를 생각해보자.

컬러를 선택하는 커스텀 뷰를 만들었다고 가정하자.

이 뷰는 아래와 같이 선택된 컬러를 전달하는 protocol 을 이지벳 method 로 사용한다.


- 일반적인 protocol, 이지벳 메서드 사용방법.


protocol ColorPicker {

func selected(color: UIColor)

}


class ColorPickerView: UIView {

weak var delegate: ColorPicker? = nil

func selected(color: UIColor){

self.이지벳?.selected(color: color)

}

}


class ViewController: UIViewController,ColorPicker{

var pickerView: ColorPickerView?

func selected(color: UIColor) {

print("selected color")

}

override func viewDidLoad() {

super.viewDidLoad()

pickerView = ColorPickerView()

pickerView?.delegate = self

}

}


만약 아래와 같은 구문으로 쓴다면 어떨까?

pickerView?.rx_selectedColor.subscribe(onNext: { color in

print("onNext")

}).addDisposableTo(disposeBag)


이렇게 이지벳 method 를 rx_이지벳 형태로 확장해보자.



1. 이지벳 Proxy 를 만들자.

Rx 의 이지벳Proxy 를 상속받고,DelegateProxyType,ColorPicker 프로토콜에 따르도록 아래와 같이 구성한다.


class RxColorPickerDelegateProxy: 이지벳Proxy,이지벳ProxyType,ColorPicker{

internal func selected(color: UIColor) {

}

static func current이지벳For(_ object: AnyObject) - AnyObject? {

let pickerView: ColorPickerView = object as! ColorPickerView

return pickerView.delegate as AnyObject?

}

static func setCurrent이지벳(_ 이지벳: AnyObject?, toObject object: AnyObject) {

let pickerView: ColorPickerView = object as! ColorPickerView

pickerView.delegate = delegate as? ColorPicker

}

}


2. 원하는 rx_메서드를 이지벳Proxy 를 통해 연결한다.


extension ColorPickerView {

public var rx_delegate: DelegateProxy {

return RxColorPickerDelegateProxy.proxyForObject(self)

}

public var rx_selectedColor: Observable<UIColor?{

returnrx_delegate.sentMessage(#selector(RxColorPickerDelegateProxy.selected(color:))).map{ a in a[0] as? UIColor }

}

}

* 여기서 a 는 selected 함수parameter를 의미한다. Observable<[Any] 로 전달 되므로필요한 형태로 mapping 해주면 된다.


3. 이제 사용하면 된다!


pickerView?.rx_selectedColor.subscribe(onNext: { color in

print("onNext")

}).addDisposableTo(disposeBag)



부록 : 이미 존재하는 RxCocoa 이지벳 의 확장

- 간단하게 2번 과정을 통해 바로 observable 을 생성하면 된다.

예를 들어 UIScrollView이지벳 의 scrollViewWillBeginDragging 를Observable 로 사용하려면


tableView.rx.이지벳

.sentMessage(#selector(UIScrollView이지벳.scrollViewWillBeginDragging(_:)))

.map{ a in a[0] as? UIScrollView }.subscribe(onNext: { scrollView in


}).addDisposableTo(disposeBag)


이렇게 해줘도 되고 위에서 확장한 것과 같이 UITableView 에서 확장해서 rx 메서드로 만들어 두고 써도 된다.




사견: RxSwift 를 프로젝트 전반적으로 사용한다면 이런 다양한 방법을 통해 코드를 일관성 있게 유지할 수 있을 것 같다. 또 이 렇게 이지벳 도 Rx 메서드로 만들어 둔다면 다른 Observable 과의 결합이나, Utility 함수들을 사용하면 더 활용도가 높을 것으로 생각한다.



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