RxSwift에서 연산자들 중에서 중요한 연산자라고 할 수 있는 변환 연산자(Transforming Operator)에 대해 정리해보려고 한다. 어제 정리한 필터링 연산자처럼 Swift 표준 라이브러리와 유사한 연산자들이 있다.
let disposeBag = DisposeBag()
Observable
.of(1,2,3)
.toArray()
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// [1,2,3]
위 코드처럼 1,2,3 요소를 .toArray() 한 다음 출력하면 [1,2,3] 이 출력되어 나온다.
map
과 같다. 수식에 맞게 변환을 한 값을 리턴한다.let disposeBag = DisposeBag()
Observable
.of(1,2,3)
.map{
$0 * 2
}
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// 2
// 4
// 6
map
에서 각 요소(1,2,3)에 *2 한 값을 반환하도록 수식을 넣어준 다음 출력하면 (2,4,6)이 출력된다.
이 부분은 보면서도 조금 헷갈려서 다시 한번 정리하면서 이해해보려고 한다...
.flatMap
을 통해서 새로운 Observable을 생성한다. 그 다음 최종적으로 각 요소의 Observable을 합친 마지막줄Observable을 생성한다.struct Item{
var price: BehaviorSubject<Int> // 가장 최신값을 알고싶을 때 사용
}
let disposeBag = DisposeBag()
let icecream = Item(price: BehaviorSubject(value: 1000))
let snack = Item(price: BehaviorSubject(value: 500))
// Observable 안에 Observable이 존재
let buyingList = PublishSubject<Item>()
buyingList
.flatMap{
$0.price
}
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
buyingList.onNext(icecream)
icecream.price.onNext(1500)
buyingList.onNext(snack)
// 1000
// 1500
// 500
먼저 BehaviorSubject
를 사용해서 가장 최신 값을 알아내려고 했고 이를 프로퍼티로 갖는 Item
구조체를 정의했다. 그 다음 icecream
과 snack
상수에 구조체 인스턴스를 할당하고 각각의 인스턴스가 갖는 초기값은 1000과 500 이다.
buyingList
상수에 PublishSubject
를 할당하는데 PublishSubject
에 들어가는 타입이 Item
구조체다. 그럼 Subject
(buyingList 상수)안에 Subject
(price 변수) 들어가는 모습을 볼 수 있다. 이 flatMap
에서는 단순히 값 변환없이 그냥 전달하고 그것을 출력해준다. 그래서 buyingList
에 onNext
이벤트가 발생할 때마다 값이 출력되는 모습을 볼 수 있습니다.
struct Item{
var price: BehaviorSubject<Int>
}
let disposeBag = DisposeBag()
let icecream = Item(price: BehaviorSubject(value: 1000))
let snack = Item(price: BehaviorSubject(value: 500))
let buyingList = PublishSubject()
buyingList
.flatMapLatest{
$0.price
}
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
buyingList.onNext(icecream)
buyingList.onNext(snack)
icecream.price.onNext(1500)
// 1000
// 500
`flatMap`과 같은 코드에서 `flatMapLatest`로만 변경했다. 그러니 출력이 1000과 500만 발생했다. 왜그러냐면! `flatMapLatest`는 `icecream` Observable과 `snack` Observable이 존재하는데 `buyingList` Observable에 `icecream`의 값을 전달하면 `icream` Observable로 전환된다. 그래서 1000이 출력이 된다. 그 다음 똑같이 `snack`의 값을 `buyingList`에 전달하면 `snack` Observable로 전환이 된다. 가장 최신의 Observable로 전환된다는 말이다. 그래서 500이 출력이 된다.
그 다음 원래 `icecream` Observable에 1500을 전달했지만 값이 출력이 되지 않았다. 그 이유는 가장 최신의 Observable은 `snack` Observable이기 때문에 다른 Observable에서 방출된 이벤트 경우는 무시된다. 그래서 출력이 되지 않은 것 이다.
이 연산자는 네트워킹 조작에서 많이 사용된다고 한다.