Combine이 가지고 있는 기능들을 정리해보았습니다. 앞으로 해당하는 글을 계속 쓰면서 업데이트 할 예정입니다.
업데이트를 하게되면 해당 설명 아래에 링크를 추가하겠습니다!
Publisher 종류
- Just: 위에서 본것과같이 가장 단순한 형태의 Publsiher로 에러타입으로 Never를 갖습니다.
- Promise: Just와 비슷하지만 Filter Type을 정의할 수 있습니다.
- Fail: 정의된 실패타입을 내보냅니다.
- Empty: 어떤 데이터도 발행하지 않는 퍼블리셔로 주로 에러처리나 옵셔널값을 처리할때 사용됩니다.
- Sequence: 데이터를 순차적으로 발행하는 Publisher로 (1…10).Publisher로 이에 해당합니다.
- ObservableObjectPublisher: SwiftUI에서 사용되는 ObservableObject를 준수하는 퍼블리셔입니다.
https://todayssky.tistory.com/17
Operator 종류
- Mapping Element
- 데이터를 다른 데이터 타입으로 변형
- Scan
- setFailureType
- map
- flatMap : 최대수 지정 후 새로운 publisher를 반환, 모든 publisher를 성공적으로 완료해도 전체 스트림은 완료되지 않고 계속 살아있음
- Filtering
- 조건에 맞는 데이터만 허용
- compactMap() : filter에서 Optional제거 → 성공적인 리턴만 반환
- replaceEmpty : empty일 경우 임의값 출력
- filter : 기본
- replaceError
- removeDuplicates : 중복 제거
- 조건에 맞는 데이터만 허용
- Reduce
- 데이터 스트림을 모아서 출력
- Collect
- reduce
- tryReduce
- ignoreOutput : 입력값을 모두 무시하고 완료 이벤트만 보냄
- Mathematic operations on
- 숫자시퀀스값과 관련된 스트림을 제어
- Max, count, min
- Sequence
- 데이터 시퀀스를 변형할때 사용
- Prepend
- firstWhere
- tryFirstWhere
- first : 클로저의 bool에 일치하는 항목중 첫번째를 가져옴
- lastWhere
- tryLastWhere
- last : 마지막을 가져옴 ( 마지막엔 copletion에 finished를 보내줘야함 )
- dropWhile : true가 될때까지 drop, true 이후로 출력(포함)
- filter와의 차이점 : filter는 모든 데이터가 해당 조건문을 비교해야함
- prefix : prefix(2) 두 값을 내보내면 publisher가 완료됨
- prefix(while: {} ) : 클로저의 결과가 true일 경우 완료
- prefix(untilOutputFrom: ) : 해당 신호가 오면 완료
- → prefix는 drop과 반대 개념인것 같음
연산자 결합
- prepend : 먼저 추가 후 publisher 완료
- append : 완료 한 후 항목 추가
- swiftchToLatest() : publisher가 바뀌면 이전 subscribe 취소
- merge(with:) : 병합
- combineLatest : 결합 → 타입이 달라도 됨 (한 쌍이 도착할 때 마다 한쪽이 기다림)
Time 연산자
- delay : 지정 시간(초) 만큼 딜레이를 준 후 값을 보냄
- collect(.byTime) : 지정 시간만큼 기다린 후 배열로 모아서 보냄
- debounce : 지정 시간을 기다린 후 출력 (일시정지)
- throttle : 지정 시간을 기다린 후 가장 최신 값을 출력 ( 일시정지 x)
- share() 연산자를 추가하면 모든 구독자가 동일한 출력을 동시에 볼 수 있음
- debounce와 비슷하지만 다름 (차이점?)
- subject.timeout : 마지막 응답 후 지정 시간이 지나면 게시가자 완료됨
- subject.measureInterval : 시간 간격 출력
Sequence 연산자
- min : 완료 이벤트를 수신한 후 최소값을 구함
- Comparable 프로토콜을 준수하지 않으면 min(by:) 클로저를 구현해야함
- max : min과 같이 완료 이벤트를 수신한 후 최대값을 구함
- first() : 첫번째값만 받고 구독취소
- .(where:) : 해당하는 첫번째 값을 받음
- last() : finished를 기다린 후 마지막 인자를 받음
- output(at :) : 해당 인덱스에 해당하는 순서까지 받음 (구독 취소됨) , (in:) : 해당 범위
publisher query
- count()
- contains() : bool을 반환 , where 사용
- allStatisy : contains의 전체버전 ( 하나라도 false시 즉시 구독 해제 및 false 리턴 )
- reudce( { } ) : 단일값을 반환
Subject
- publisher의 일종
- 외부의 데이터를 안으로 주입시킬 수 있음 → SwiftUI같은 다른 Framework와도 쉽게 연동 가능
- PassthroughSubject
- 상태값을 가지지 않음
- CurrentValueSubject
- 상태값을 가짐
- UI 상태값에 따라 데이터를 발행할 때 유용
Cancellable
- Subscriber의 리턴값
- cancle() 메서드로 스트림 중단 가능
eraseToAnyPublisher
- 데이터 스트림과 상관없이 최종적인 형태의 Publisher를 리턴
리소스 관리
- share()
- multicast
- future class
사용할만한 소스
- 시간 간격 출력
class TimeLogger: TextOutputStream {
private var previous = Date()
private let formatter = NumberFormatter()
init() {
formatter.maximumFractionDigits = 5
formatter.minimumFractionDigits = 5
}
func write(_ string: String) {
let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return }
let now = Date()
print("+\(formatter.string(for: now.timeIntervalSince(previous))!)s: \(string)")
previous = now
}
}
/* ex)
let subscription = (1...3).publisher
.print("publisher", to: TimeLogger())
.sink { _ in }
*/
- http decode
func story(id: Int) -> AnyPublisher<Story, Error> {
URLSession.shared
.dataTaskPublisher(for: EndPoint.story(id).url)
.receive(on: apiQueue) // 수신할 스케줄러를 정의
.map(\.data)
.decode(type: Story.self, decoder: decoder)
.catch { _ in Empty<Story, Error>() } // 게시자의 오류를 다른 게시자로 대체
.eraseToAnyPublisher()
}
// 커스텀 디버그 스트링
extension Story: CustomDebugStringConvertible {
public var debugDescription: String {
return "\n\(title)\nby \(by)\n\(url)\n\(id)\n\(time)\n-----"
}
}
반응형
'ios > Combine' 카테고리의 다른 글
Swift - Combine의 Publisher 알아보기 Just, Future, Fail, Empty, Deferred, Sequence (0) | 2022.02.08 |
---|---|
SwiftUI - Combine (3) Combine의 생명 주기(Life Cycle) (0) | 2022.01.21 |
SwiftUI - Combine (2) 핵심 개념 (Publisher, Subscriber, Operator, Subject) (0) | 2022.01.20 |
SwiftUI - Combine (1) 소개 Combine을 사용하는 이유 (0) | 2022.01.18 |