본문 바로가기
IOS🍎/RxSwift

[RxSwift] Signal, ControlProperty, ControlEvent 란 ?

by Jouureee 2022. 3. 21.

저번 Driver에 이어서 나머지 Trait들도 마저 다 살펴보려고 합니다.

 

Signal

signal은 Driver와 유사합니다.

하지만 Driver는 subscribe할 때 한번 replay 하는 반면, Signal은 그렇지 않습니다.

Driver와 Signal을 구독하게 되면 다음과 같이 replay 합니다.

PublishRelay와 BehaviorRelay과 같이 Signal은 구독 이후의 이벤트를 방출하고 Driver은 구독을 하면 가장 최근의 이벤트를 방출한다는 점에서 차이점이 있습니다.

 

ControlProperty

UI Element의 property를 나타내기 위한 Trait

특징

  • 실패하지 않는다.
  • share(replay: 1) 처럼 행동한다 - stateful, subscribe 호출 시 마지막 element가 생성되면 즉시 replay 한다.
  • 메인 쓰레드에서 실행된다.
  • 에러를 방출하지 않는다.
  • deallocated될 때 complete된다

아래 예시를 통해서 자세히 살펴보겠습니다.

UISearchBar+Rx

extension Reactive where Base: UISearchBar {
    /// Reactive wrapper for `text` property.
    public var value: ControlProperty<String?> {
        let source: Observable<String?> = Observable.deferred { [weak searchBar = self.base as UISearchBar] () -> Observable<String?> in
            let text = searchBar?.text
            
            return (searchBar?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBar(_:textDidChange:))) ?? Observable.empty())
                    .map { a in
                        return a[1] as? String
                    }
                    .startWith(text)
        }

        let bindingObserver = Binder(self.base) { (searchBar, text: String?) in
            searchBar.text = text
        }
        
        return ControlProperty(values: source, valueSink: bindingObserver)
    }
}

UISegmentedControl+Rx

extension Reactive where Base: UISegmentedControl {
    /// Reactive wrapper for `selectedSegmentIndex` property.
    public var selectedSegmentIndex: ControlProperty<Int> {
        value
    }
    
    /// Reactive wrapper for `selectedSegmentIndex` property.
    public var value: ControlProperty<Int> {
        return UIControl.rx.value(
            self.base,
            getter: { segmentedControl in
                segmentedControl.selectedSegmentIndex
            }, setter: { segmentedControl, value in
                segmentedControl.selectedSegmentIndex = value
            }
        )
    }
}

 

ControlEvent

controlProverty와 같이 UI Element의 property를 나타내기 위한 Trait

특징

  • 실패하지 않는다.
  • subscribe에게 초기값을 전달하지 않는다.
  • 메인 쓰레드에서 실행된다.
  • 에러를 방출하지 않는다.
  • deallocated될 때 complete된다
public extension Reactive where Base: UIViewController {
    
    /// Reactive wrapper for `viewDidLoad` message `UIViewController:viewDidLoad:`.
    public var viewDidLoad: ControlEvent<Void> {
        let source = self.methodInvoked(#selector(Base.viewDidLoad)).map { _ in }
        return ControlEvent(events: source)
    }
}

 

extension Reactive where Base: UICollectionView {
    
    /// Reactive wrapper for `delegate` message `collectionView:didSelectItemAtIndexPath:`.
    public var itemSelected: ControlEvent<IndexPath> {
        let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didSelectItemAt:)))
            .map { a in
                return a[1] as! IndexPath
            }
        
        return ControlEvent(events: source)
    }
}

 

'IOS🍎 > RxSwift' 카테고리의 다른 글

[RxSwift] Error Handling Operator  (0) 2022.05.10
[RxSwift] Schedular란 (subscribeOn, observeOn)  (0) 2022.04.29
[RxSwift] Driver란 ? (feat. bind)  (0) 2022.03.21
[RxSwift] Traits 이란  (0) 2022.03.19
[RxSwift] Disposable DisposeBag 이란  (0) 2022.03.17

댓글