collect, map, replace, scan
* 이글은 Swift 5 기준으로 작성했다.
Combine 의다양한 Transform Operators 들을 알아보자
finish 될때까지 이벤트를 모두 모아준다.
* 주의: 갯수에 한계치가 없으므로 메모리 관리에 주의해야 한다.
subject.collect().sink {
print($0)
} receiveValue: {
print($0)
}.store(in: &cancellable)
일정한 시간간격(500ms)을 두고 sujbect를 통해 이벤트를 전달하고 collect 한 로그이다.
2021-05-01 14:39:42 +0000 emit 1
2021-05-01 14:39:43 +0000 emit 2
2021-05-01 14:39:43 +0000 emit 3
[1, 2, 3]
finished
주어진 count 만큼 모아서 이벤트가 전달된다. finish 가 되면 담겨져있는 만큼의 이벤트가 전달된뒤 종료된다.
2021-05-01 14:49:00 +0000 emit 1
2021-05-01 14:49:01 +0000 emit 2
[1, 2]
2021-05-01 14:49:02 +0000 emit 3
2021-05-01 14:49:02 +0000 emit 4
[3, 4]
2021-05-01 14:49:03 +0000 emit 5
[5]
finished
Publishers.TimeGroupingStategy 의 종류
문서: https://developer.apple.com/documentation/combine/publishers/timegroupingstrategy
- byTime(Context, Context.SchedulerTimeType.Stride)
주어진 스케쥴러와 시간동안 발생한 이벤트를 모아 전달한다.
subject.collect(.byTime(DispatchQueue.main, .seconds(1))).sink {
print($0)
} receiveValue: {
print($0)
}.store(in: &cancellable)
2021-05-01 14:58:06 +0000 emit 0
2021-05-01 14:58:07 +0000 emit 1
[0, 1]
2021-05-01 14:58:07 +0000 emit 2
2021-05-01 14:58:08 +0000 emit 3
2021-05-01 14:58:08 +0000 emit 4
[2, 3, 4]
2021-05-01 14:58:09 +0000 emit 5
[5]
2021-05-01 14:58:09 +0000 emit 6
[6]
finished
- byTimeOrCount(Context, Context.SchedulerTimeType.Stride, Int)
주어진 스케쥴러와, 카운트 의 조건이 맞으면 이벤트가 발생한다.
subject.collect(.byTimeOrCount(DispatchQueue.main, .milliseconds(700), 2)).sink {
print($0)
} receiveValue: {
print($0)
}.store(in: &cancellable)
그림과 온전히 일치하는 예제를 만들진 못했지만 로그는 아래와 같다.
2021-05-01 15:03:30 +0000 emit 0
2021-05-01 15:03:31 +0000 emit 1
[0, 1]
2021-05-01 15:03:31 +0000 emit 2
[2]
2021-05-01 15:03:32 +0000 emit 3
[3]
2021-05-01 15:03:32 +0000 emit 4
2021-05-01 15:03:33 +0000 emit 5
[4, 5]
2021-05-01 15:03:33 +0000 emit 6
[6]
finished
Swift 의 표준 map 과 동일하게 이해하면 된다. 값을 변형한다.
예제는 생략... :D
- map<T>(_:)
- map<T0, T1>(_:_:)
- map<T0, T1, T2>(_:_:_:)
Key path 를 통해 map이 가능하다.
예를 들어 CGPoint 로 이벤트가 나온다고 하면 아래와 같이 작성할수 있다.
subject.map(\.x, \.y)
.sink {
print($0)
} receiveValue: {
print($0, $1)
}.store(in: &cancellable)
2021-05-01 15:16:34 +0000 emit 0
0.0 0.0
2021-05-01 15:16:35 +0000 emit 1
1.0 1.0
finished
.map(\.x, \.y) 를 .map(\.x) 등으로 필요한 key paths 로 유용하게 사용가능하다.
try 구문을 사용 할수 있다. 에러가 발생하면 failure 로 전달된다.
publisher.tryMap{ try FileManager.default.contentsOfDirectory(atPath: $0) }
.sink {
print($0)
} receiveValue: {
print($0, $1)
}.store(in: &cancellable)
failure("blabla")
flatMap 은 element 로부터 새로운 publisher 를 리턴한다.
같은 타입의 downstream publisher 들을 하나의 publisher 로 변경한다.
검색 키워드로 google 검색을 하도록 작성해본 예제이다.
최대 publisher 의 갯수를 지정할수 있다.
위의 그림처럼 2개의 publisher 의 이벤트만 전달된다.
nil 이 전달될때 지정한 값으로 치환한다.
empty 일때 주어진 값의 이벤트를 방출
initial Value 를 가지고 계산값을 축적한다.
Swift 의 기본 함수와 비슷한 동작을 가지는 것들이 있어서 어렵지는 않은것 같다 :D
마침.