본문 바로가기
iOS📱/Combine

[Combine] 다양한 Publisher 들 1 ( Just, Future, Deferred )

by 텅빈비니 2024. 2. 8.
반응형

안녕하세요🐶

빈지식 채우기의 비니🙋🏻‍♂️입니다.

.

이전 Combine 포스팅에서는 Publisher 와 Subscriber 에 대해 알아봤습니다.

 

[Combine] Publisher 와 Subscriber

안녕하세요🐶 빈지식 채우기의 비니🙋🏻‍♂️입니다. 지난 글에서는 간단히 Combine에 대해 알아보았습니다. . 간단히 요약하면 Apple에서 2019년에 만든 프레임워크로서, RxSwift와 같이 비동기

beanistory.tistory.com


간단히 말해 Publisher란,

Subscription을 만들고 Subscriber 에게 값과 Completion Event 를 내보내는 타입을 위한 프로토콜


 

RxSwift 에서도 just, from, of 와 같은 Operator가 존재했다면,

Combine 역시 미리 정의된 Publisher 들이 있습니다.

  • Just
  • Future
  • Deferred
  • Empty
  • Fail
  • Record
  • AnyPublisher

오늘 포스팅은 위와 같이 Combine 에서 사용되는 Publisher에 대해 알아보도록 하겠습니다.


1. Just

자신을 Subscribe(구독) 하는 Subscriber(구독자) 들에게 한 번에 값을 보낸 뒤, Finish 이벤트를 보내는 Publihser
func just() {
    let just = Just("This is Just output")
    let _ = just.sink { completion in
        print("Received Just Completion : \(completion)")
    } receiveValue: { v in
        print("Received Just Value : \(v)")
    }

}

결과 로그

하나의 값만 보내기 때문에, 값 도출 후 Finished 이벤트가 전달되었습니다.


❗️여기서 잠깐❗️

 

앞서 포스팅에서는 Publisher 프로토콜은 Output, Failure 프로퍼티가 필요하다고 했었는데,

Just는 왜 따라 Failure 타입을 서정하지 않았나요?

이렇게 위와 같이 Failure 타입이 Never 로 설정되어 있기 때문입니다.

Never 란, 정상적으로 리턴하지 않는 함수의 리턴 타입 이라는 의미이기 때문에,

따로 Failure 타입을 설정하지 않았습니다.


 


2. Future

하나의 결과를 비동기로 생성한 뒤 Completion Event를 보내는 Publisher
Callback 기반 Completion Handler 와 비슷한 동작을 한다.

Future 의 경우 Output Error 를 가지고 있습니다.

Promise 클로져가 있는데 이 부분은 예제로 바로 알아보도록 하겠습니다.

func future() {
    let future = Future<Int, Never> { promise in
        promise(.success(1))
        promise(.success(2))	// 단일값 전달이기 때문에 해당 값은 전달이 안된다.
    }

    let _ = future.sink(
        receiveCompletion: {
            print($0)
        },
        receiveValue: {
            print($0)
        }
    )

    print("end")
}

결과 로그

  • Future 는 단일 값 전달이기 때문에 success(2) 부분은 출력이 안됨

3. Deferred

Lazy 와 비슷하게 Publisher가 실제로 사용될 때 Publisher를 생성해서 사용
메모리를 효율적으로 사용 가능

Deferred의 경우 Output  Error 를 가지고 있습니다.

  • createPublisherPublisher가 Subscribe 됐을 때 실행할 클로저입니다.
  • init에서 받은 클로저Subscribe가 호출될 때 실행됩니다.
func deferred() {
    struct customPublisher: Publisher {
        typealias Output = String
        typealias Failure = Never

        func receive<S>(subscriber: S) where S : Subscriber, Never == S.Failure, String == S.Input {
            subscriber.receive("나는 Publisher 입니다.")
            subscriber.receive(completion: .finished)
        }
    }

    print("Deferred Publisher 생성")
    let deferred = Deferred { () -> customPublisher in
        print("Publisher가 만들어짐")
        return customPublisher()
    }

    let _ = deferred
        .sink(
            receiveCompletion: {
                print($0)
            },
            receiveValue: {
                print($0)
            }
        )
}

결과 로그

  • Deferred가 만들어졌을 때에는 새로 만든 Publisher가 바로 만들어지지 않음.
  • 이후 Sink 를 통해 Subscribe 했을 때, Deferred 를 생성할 때 구현한 클로저(Publisher)가 만들어짐.

 


이상으로 다양한 Publihser들 1 포스팅을 마치겠습니다.

감사합니다!


참고

반응형

'iOS📱 > Combine' 카테고리의 다른 글

[Combine] Publisher 와 Subscriber  (2) 2024.02.01
[Combine] Combine 이란?  (2) 2024.01.26