티스토리 뷰
RxCocoa traits
RxSwift 문서를 정리 및 요약해보겠습니다. (출처 - RxCocoa Traits)
ControlProperty 와 ControlEvent 는 UI 요소의 속성을 나타내는 Observable/ObservableType 의 trait 입니다.
👉 ControlProperty
ControlProperty 는 ObservableType 과 ObserverType 을 동시에 채택하는 ControlPropetyType 을 채택합니다.
Subject 와 같이 프로퍼티에 새로운 값을 관찰할 수도 방출할 수도 있습니다.
public struct ControlProperty<PropertyType> : ControlPropertyType {
...
}
/// Protocol that enables extension of `ControlProperty`.
public protocol ControlPropertyType : ObservableType, ObserverType {
/// - returns: `ControlProperty` interface
func asControlProperty() -> ControlProperty<Element>
}
예를 들어, UITextField+Rx.Swift
에서는 다음과 같이 text 를 ControlProperty 로 가집니다.
extension Reactive where Base: UITextField { ...
public var text: ControlProperty<String?> {
return value
}
...
}
Observable 채택한 text 에 대한 변경사항을 관찰하기 위해서 subscribe 를 수행할 수 있습니다.
ObserverType 채택하였기 때문에 다음과 같이 사용할 수 있습니다.
drive(_:) 와 bind(to:) 는 ObserverType 을 채택한 객체를 파라미터로 전달할 수 있습니다.
.drive(textfield.rx.text)
.bind(to: textfield.rx.text)
위의 예시처럼 ControlProperty 는 시퀀스가 오직 초기 control value 와 사용자가 시작한 값 변경만을 나타냅니다.
속성은 다음과 같습니다.
- never fails
- never errors out
- UI 작업에 특화되있는 RxCocoa 의 Trait 이기 때문에 스트림이 끊기지 않도록 실패를 하지 않도록 합니다.
share(replay: 1)
behavior- 구독 시에 마지막 요소가 있는 경우 즉시 replay 됩니다.
- 할당 해제될때
Complete
방출됩니다. MainScheduler.instance
에 이벤트를 전달합니다.ControlEvent
의 구현은 이벤트 시퀀스가 main scheduler(subscribeOn(ConcurrentMainScheduler.instance)
동작)에서 구독되도록 합니다.
좀 더 예시 코드를 살펴보겠습니다. UISearchBar+Rx.swift
에서는 text 를
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 에서는 selectedSegmentIndex
를 래핑하고 있습니다.
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
ControlEvent
는 ObservableType
을 채택하는 ControlEventType
을 채택합니다.
public struct ControlEvent<PropertyType> : ControlEventType {
...
}
/// A protocol that extends `ControlEvent`.
public protocol ControlEventType : ObservableType {
/// - returns: `ControlEvent` interface
func asControlEvent() -> ControlEvent<Element>
}
속성은 다음과 같습니다.
- never fails
- never errors out
- UI 작업에 특화되있는 RxCocoa 의 Trait 이기 때문에 스트림이 끊기지 않도록 실패를 하지 않도록 합니다.
- 구독 시 초기 값을 보내지 않습니다.
- 할당 해제될때
Complete
방출됩니다. MainScheduler.instance
에 이벤트를 전달합니다.ControlEvent
의 구현은 이벤트 시퀀스가 main scheduler(subscribeOn(ConcurrentMainScheduler.instance)
동작)에서 구독되도록 합니다.
예를 들어, UIButton+Rx.Swift
extension Reactive where Base: UIButton {
/// Reactive wrapper for `TouchUpInside` control event.
public var tap: ControlEvent<Void> {
controlEvent(.touchUpInside)
}
}
UICollectionView+Rx.swift
에서도 확인할 수 있습니다.
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)
}
}
tap
, itemSelected
의 변경사항을 관찰하기 위해서 subscribe 을 사용할 수 있습니다.
출처 :
https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Traits.md
'iOS > RxSwift' 카테고리의 다른 글
iOS) MVVM + RxSwift, RxCocoa 적용 (0) | 2023.08.31 |
---|---|
RxSwift) withUnretained 와 이를 대체하는 subscribe(with:onNext:…) (0) | 2023.07.05 |
RxSwift) Traits(1) - Driver, Signal (0) | 2023.02.27 |
RxSwift) error handling - catch, catchAndReturn, retry, retry(when:), materialize, dematerialize (0) | 2023.02.17 |
RxSwift) 6.Subjects (0) | 2022.07.14 |
- Objective-C
- Protocol
- projectsetting
- OpenSourceLibrary
- Widget
- github
- WWDC
- urlsession
- rxswift
- CloneCoding
- APNS
- MOYA
- Firebase
- Algorithm
- Swift
- containerBackground
- UserDefaults
- RxCocoa
- 서버통신
- IOS
- async/await
- YPImagePicker
- WidgetKit
- WWDC22
- SwiftUI
- configurable widget
- MVVM
- watchOS
- 2022 KAKAO TECH INTERNSHIP
- Notification
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Total
- Today
- Yesterday