일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- clean architecture
- MVVM
- Clean Code
- Protocol
- HIG
- 클린 코드
- 스위프트
- uiscrollview
- combine
- 리펙토링
- Human interface guide
- ribs
- uitableview
- map
- swiftUI
- 리팩토링
- 애니메이션
- UICollectionView
- UITextView
- collectionview
- rxswift
- 리펙터링
- RxCocoa
- swift documentation
- Observable
- tableView
- Refactoring
- SWIFT
- Xcode
- ios
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[RxSwift] 9. Combining Operators 본문
1. Prefixing and concatenating
- Observable끼리 합치는 것
1) startWith(value)
- 기존 리스트에 첫 번째에 추가
example(of: "startWith") {
// 1
let numbers = Observable.of(2, 3, 4)
// 2
let observable = numbers.startWith(1)
_ = observable.subscribe(onNext: { value in
print(value)
})
}
2) concat([])
example(of: "Observable.concat") {
// 1
let first = Observable.of(1, 2, 3)
let second = Observable.of(4, 5, 6)
// 2
let observable = Observable.concat([first, second])
observable.subscribe(onNext: { value in
print(value)
})
}
※ 단, Observable.contat()에 들어가는 것은 무조건 동일 타입이어야 함
3) merge
두 개의 Observable Sequence를 하나의 Observable Sequence로 합침
example(of: "merge") {
// 1
let left = PublishSubject<String>()
let right = PublishSubject<String>()
// 2
let source = Observable.of(left.asObservable(), right.asObservable())
// 3
let observable = source.merge()
let disposable = observable.subscribe(onNext: { value in
print(value)
})
// 4
var leftValues = ["Berlin", "Munich", "Frankfurt"]
var rightValues = ["Madrid", "Barcelona", "Valencia"]
repeat {
switch Bool.random() {
case true where !leftValues.isEmpty:
left.onNext("Left: " + leftValues.removeFirst())
case false where !rightValues.isEmpty:
right.onNext("Right: " + rightValues.removeFirst())
default:
break
}
} while !leftValues.isEmpty || !rightValues.isEmpty
// 5
left.onCompleted()
right.onCompleted()
}
/* prints
Left: Berlin
Right: Madrid
Left: Munich
Right: Barcelona
Left: Frankfurt
Right: Valencia
*/
4) combineLatest
하나의 이벤트만 저장 가능했던 Observable Sequence를 여러 개의 이벤트를 저장하게끔 함
- left를 기준으로해서 right가 나중에 나오면 모두 left에서의 최신 값과 매칭
example(of: "combineLatest") {
let left = PublishSubject<String>()
let right = PublishSubject<String>()
// 1
let observable = Observable.combineLatest(left, right) {
lastLeft, lastRight in
"\(lastLeft) \(lastRight)"
}
let disposable = observable.subscribe(onNext: { value in
print(value)
})
// 2
print("> Sending a value to Left")
left.onNext("Hello,")
print("> Sending a value to Right")
right.onNext("world") // print : Hello, world
print("> Sending another value to Right")
right.onNext("RxSwift") // print : Hello, RxSwift
print("> Sending another value to Left")
left.onNext("Have a good day,") // print : Have a good day RxSwift
left.onCompleted()
right.onCompleted()
}
ex2) 현재 시간으로 로그 남기기
example(of: "combine user choice and value") {
let choice: Observable<DateFormatter.Style> = Observable.of(.short, .long)
let dates = Observable.of(Date())
let observable = Observable.combineLatest(choice, dates) {
format, when -> String in
let formatter = DateFormatter()
formatter.dateStyle = format
return formatter.string(from: when)
}
_ = observable.subscribe(onNext: { value in
print(value)
})
}
5) zip
- combineLatest와 최근의 이벤트들과 짝지어지지만, 갯수 제한이 생김
example(of: "zip") {
enum Weather {
case cloudy
case sunny
}
let left: Observable<Weather> = Observable.of(.sunny, .cloudy, .cloudy, .sunny)
let right = Observable.of("Lisbon", "Copenhagen", "London", "Madrid", "Vienna")
let observable = Observable.zip(left, right) { weather, city in
return "It's \(weather) in \(city)"
}
_ = observable.subscribe(onNext: { value in
print(value)
})
}
/* prints :
It's sunny in Lisbon
It's cloudy in Copenhagen
It's cloudy in London
It's sunny in Madrid
*/
2. Triggers
특정 시점에 observable들을 받아들여야 하는 경우에 이용
1) withLatestFrom
example(of: "withLatestFrom") {
// 1
let button = PublishSubject<Void>()
let textField = PublishSubject<String>()
// 2
let observable = button.withLatestFrom(textField)
_ = observable.subscribe(onNext: { value in
print(value)
})
// 3
textField.onNext("Par")
textField.onNext("Pari")
textField.onNext("Paris")
button.onNext(())
button.onNext(())
}
/*
Paris
Paris
*/
2) sample
- withLatestFrom과 기능 동일, 단 1회성 emit
3. switches
subscriber가 어떤 sequence의 이벤트를 수신할지 결정
1) amb
- ambiguous(모호한) : 먼저 온 sequence만 구독
- server에서 대량의 데이터가 오는 경우 사용
example(of: "amb") {
let left = PublishSubject<String>()
let right = PublishSubject<String>()
// 1
let observable = left.amb(right)
let disposable = observable.subscribe(onNext: { value in
print(value)
})
// 2
left.onNext("Lisbon")
right.onNext("Copenhagen")
left.onNext("London")
left.onNext("Madrid")
right.onNext("Vienna")
left.onCompleted()
right.onCompleted()
}
/* print
Lisbon
London
Madrid
*/
2) switchLatest
- emit할 시퀀스를 선택할 수 있게끔 함
// 1
let one = PublishSubject<String>()
let two = PublishSubject<String>()
let three = PublishSubject<String>()
let source = PublishSubject<Observable<String>>()
// 2
let observable = source.switchLatest()
let disposable = observable.subscribe(onNext: { value in
print(value)
})
// 3
source.onNext(one)
one.onNext("Some text from sequence one")
two.onNext("Some text from sequence two")
source.onNext(two)
two.onNext("More text from sequence two")
one.onNext("and also from sequence one")
source.onNext(three)
two.onNext("Why don't you see me?")
one.onNext("I'm alone, help me")
three.onNext("Hey it's three. I win.")
source.onNext(one)
one.onNext("Nope. It's me, one!")
disposable.dispose()
}
/* prints
Some text from sequence one
More text from sequence two
Hey it's three. I win.
Nope. It's me, one!
*/
4. sequence내의 요소들간 결합
higher-order function에서의 reduce와 기능 동일
1) reduce(::)
- reduce(init, accumulator)
example(of: "reduce") {
let source = Observable.of(1, 3, 5, 7, 9)
// 1
let observable = source.reduce(0, accumulator: +)
observable.subscribe(onNext: { print($0) } )
}
(위와 동일한 코드)
// 2
let observable2 = source.reduce(0, accumulator: { summary, newValue in
return summary + newValue
})
observable2.subscribe(onNext: { print($0) })
2) scan(_:accumulator:)
- reduce(::)와 같이 작동하지만 리턴값이 Observable이며 하나의 값으로 나오는게 아니고 누적되며 emit
example(of: "scan") {
let source = Observable.of(1, 3, 5, 7, 9)
let observable = source.scan(0, accumulator: +)
observable.subscribe(onNext: { print($0) })
/* Prints:
1
4
9
16
25
*/
}
'RxSwift > RxSwift 기본' 카테고리의 다른 글
[RxSwift] 11. Time-Based Operators (delay, timeout) (0) | 2020.06.24 |
---|---|
[RxSwift] 10. share Operators (0) | 2020.06.24 |
[RxSwift] 8. Transforming Operators 실전(RESTful API) (0) | 2020.06.04 |
[RxSwift] 7.Transforming Operators (0) | 2020.06.01 |
[RxSwift] 6.Filtering Operators 실습 (0) | 2020.05.29 |