IOS - Swift/Combine

Publisher - Just, Empty, Failure

게게겍 2024. 10. 3. 17:18

 

Just

Just는 가장 기본적인 Publisher 입니다.

한 개의 아웃풋을 각각의 Subscriber에게 단 한 번 보내고, 종료합니다.

다시말해서, 자신을 구독(subscribe)하는 구독자(subscriber)들에게 한번의 값만 전송하고 finish 하는 Publisher 입니다

실제 코드로 보면, Failure가 Never로 고정되어있습니다.

즉, Just는 에러를 발행할 수 없고 무조건 Output만 발행될 수 있다는것을 의미합니다.

public struct Just<Output> : Publisher {
    public typealias Failure = Never
    public let output: Output

    public init(_ output: Output)

    public func receive<S>(subscriber: S) where Output == S.Input, S : Subscriber, S.Failure == Never
}

사용

import Combine

let justPublisher = Just(5)

let subscription = justPublisher.sink { value in
    print("Received value: \\(value)")
}

// 출력값
// Received value: 5

정리

  • 에러를 보낼 수 없다 (Failure 타입 Never)
  • 한 번 값을 방출하면 더 이상 추가 방출이 불가능하다.
  • 한 번 값을 방출하면 완료(.finished) 된다.

Empty

Empty는 값을 발행하지 않고 선택적으로 즉시 스트림을 종료할 수 있는 Publisher입니다.

진짜 말 그대로 아무런 값도 내보내지 않고 즉시 성공 (completion) 이벤트를 보낼수 있는 publisher 입니다.

completeImmediately

Empty에서 가장 중요한 매개변수는 completeImmediately 이라고 생각합니다.

completeImmediately는 Empty Publisher의 생성자에서 사용되는 Bool값입니다.

이 매개변수는 Empty Publisher가 생성된 직후 즉시 완료 신호를 보낼지 여부를 결정합니다.

기본값으로는 True로 설정되어있습니다.

  1. completeImmediately: true
    • Empty 퍼블리셔는 생성 즉시 완료 신호를 보냅니다.
    • 구독자는 값을 받지 않고 바로 완료 이벤트를 받게 됩니다.
    • 다른 퍼블리셔와 조합하여 사용할 때, 즉시 스트림을 종료시키는 효과가 있습니다.
  2. completeImmediately: false
    • Empty 퍼블리셔는 완료 신호를 보내지 않고 대기 상태를 유지합니다.
    • 구독자는 어떠한 이벤트도 받지 않으며, 스트림은 계속 열린 상태로 유지됩니다.
    • 다른 퍼블리셔와 조합하여 사용할 때, 스트림을 열린 상태로 유지하면서 아무 동작도 하지 않게 만듭니다.

false로 설정하면 완료 이벤트가 발행되지 않아요.

사용

import Combine

let trueEmptyPublisher = Empty<Int, Never>(completeImmediately: true)
let falseEmptyPublisher = Empty<Int, Never>(completeImmediately: false)

print("True Empty Publisher:")
let trueCancellable = trueEmptyPublisher
    .sink(receiveCompletion: { completion in
        print("Completed: \\(completion)")
    }, receiveValue: { value in
        print("Received value: \\(value)")
    })

print("\\nFalse Empty Publisher:")
let falseCancellable = falseEmptyPublisher
    .sink(receiveCompletion: { completion in
        print("Completed: \\(completion)")
    }, receiveValue: { value in
        print("Received value: \\(value)")
    })

// 잠깐만~
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    print("\\nCancelling subscriptions")
    trueCancellable.cancel()
    falseCancellable.cancel()
}


///출력
///True Empty Publisher:
///Completed: finished

///False Empty Publisher:

///Cancelling subscriptions

즉,

completeImmediately: true로 설정된 퍼블리셔는 즉시 완료 이벤트를 발생시킵니다.

completeImmediately: false로 설정된 퍼블리셔는 아무 이벤트도 발생시키지 않습니다

정리

  • 값을 발행하지 않고 아무런 데이터도 전송하지 않을때 사용된다.
  • 에러타입을 ‘지정’할 수 있다 (발행아님).
  • completeImmediately 파라미터를 통해서 구독 직후에 완료 이벤트를 발행할 것인지 결정할 수 있다.

Fail

Fail은 에러가 나는 즉시 데이터 스트림을 종료하는 Publisher입니다.

위에서 Empty가 completion 이벤트를 즉시 보낼 수 있었다면 Fail은 Error를 즉시 보낼 수 있는 Publisher입니다

사용

import Combine

// 1. 간단한 에러 타입 정의
enum SimpleError: Error {
    case somethingWentWrong
}

// 2. Fail 퍼블리셔 생성
let failPublisher = Fail<String, SimpleError>(error: .somethingWentWrong)

// 3. 구독
let cancellable = failPublisher.sink(
    receiveCompletion: { completion in
        switch completion {
        case .finished:
            print("완료")
        case .failure(let error):
            print("에러 발생: \\(error)")
        }
    },
    receiveValue: { value in
        print("값 받음: \\(value)")
    }
)
  1. SimpleError라는 간단한 에러 타입을 만듭니다.
  2. Fail 퍼블리셔를 생성합니다. 이 퍼블리셔는 String 타입의 값을 발행할 수 있지만 (실제로는 발행하지 않음), SimpleError 타입의 에러를 발생시킵니다.
  3. 이 퍼블리셔를 구독합니다.
  • Fail 퍼블리셔는 즉시 에러를 발생시키고 종료됩니다.
  • 값을 받는 클로저는 실행되지 않습니다.
  • 완료 클로저에서 에러를 받아 처리합니다.

특징

  • 오직 에러만을 발행하고 값(Output)을 발행하지 않는다.
  • Failure을 발행하기 때문에 즉시 스트림이 종료됩니다.