Combine이 가지고 있는 기능들을 정리해보았습니다. 앞으로 해당하는 글을 계속 쓰면서 업데이트 할 예정입니다.

업데이트를 하게되면 해당 설명 아래에 링크를 추가하겠습니다!

 

Publisher 종류 

  1. Just: 위에서 본것과같이 가장 단순한 형태의 Publsiher로 에러타입으로 Never를 갖습니다.
  2. Promise: Just와 비슷하지만 Filter Type을 정의할 수 있습니다.
  3. Fail: 정의된 실패타입을 내보냅니다.
  4. Empty: 어떤 데이터도 발행하지 않는 퍼블리셔로 주로 에러처리나 옵셔널값을 처리할때 사용됩니다.
  5. Sequence: 데이터를 순차적으로 발행하는 Publisher로 (1…10).Publisher로 이에 해당합니다.
  6. ObservableObjectPublisher: SwiftUI에서 사용되는 ObservableObject를 준수하는 퍼블리셔입니다.

 

Swift - Combine의 Publisher 알아보기 Just, Future, Fail, Empty, Deferred, Sequence

Publisher #Combine #Publisher Just 가장 단순한 형태의 Publisher 입니다. 에러 타입은 항상 Never 입니다. Just((0...5)) .sink { value in print(value) // 0...5 } Future 일반적으로 Publisher의 처리를 sin..

todayssky.tistory.com

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-----"
  }
}
반응형

+ Recent posts