brunch

You can make anything
by writing

C.S.Lewis

by Tilltue Apr 24. 2021

Publishers, Subscribers 알아보기

Swift Combine

* 이글은 Swift 5 기준으로 작성했다.


Publishers, Subscribers 는 Combine 을 시작하고 주요하게 접하게 되는 것들이다.




1. Publisher Protocol


애플 문서 : https://developer.apple.com/documentation/combine/publisher

Publisher 프로토콜은 시간이 지남에 따라 값을 전달할수 있는 타입임을 명시한다.

 

개요

Publisher는 하나 이상의 Subscriber 인스턴스에게 요소들(값들)을 전달한다.

Publisher 프로토콜을 준수하기 위한 최소 코드는 아래와 같다.

보이는 것처럼 Subscriber 의 Failure 와 Publisher 의 Failure 는 동일해야 하고,

Subscriber 의 Input 과 Publisher 의 Output 이 동일해야 한다.


publisher 는 recieve ( 구독자를 수락하는 ) 메서드를 구현하고 이후 구독자에게 요소를 전달하거나, 종료 ( 완료 혹은 에러 ) 를 전달할수 있다.

* Failure 를 Never 타입으로 두면 종료는 에러 없이 완료로만 구성된다.


2. Subscriber Protocol


애플 문서: https://developer.apple.com/documentation/combine/subscriber

Subscriber 프로토콜은 Publisher로부터 입력을 받을수 있는 타입임을 명시한다.


개요

Subscriber 는 Publisher 로부터 elements 스트림을 받는다.

Subscriber 프토토콜을 준수하기 위한 최소 코드는 아래와 같다.

Subscriber 의 Input, Failure 는 연결하고자 하는 Publisher 의 Output, Failure 와 일치해야 한다.


3. Subscription Protocol


애플 문서: https://developer.apple.com/documentation/combine/subscription

Subscription 은 Publisher 와 Subscriber 의 연결을 나타나는 프로토콜이다.


개요

Subscription 은 class 로 제한된다. 그 이유는 Publisher 와 Subscriber 가 연결될때 Subscription 의 고유 식별자가 필요하기 때문이다. ( CombineIdentifier ) 또한 cancel 동작은 thread-safe 해야 한다. cancel 동작은 한번만 가능하며 cancel 에서 subscriber 연결시 할당했던 자원을 해제할 수 있다.


Subscription 프로토콜을 준수하기 위한 최소 코드는 아래와 같다.


4. Publisher 와 Subscriber 연결 및 동작 과정


위의 설명으로 보면 publisher 는 데이터를 전달하고 Subscriber 는 데이터를 수신받는 타입이고 메서드는 단순해보인다. 하지만 실제 동작과정은 조금은 복잡하다.


Publisher 와 Subscriber 의 연결은 Subscription 을 통해 더 깊게 연결된다.

Subscription 인스턴스를 통해 Subscriber 는 값을 요청하고 이후 값을 받을수 있다. ( 원한다면 수신 받을 값의 갯수 제한도 가능하다 )


아래 그림은 Publisher 와 Subscriber 의 연결, 동작 과정을 도식화 한 것이다.

1.  subscriber 로 부터 구독요청을 받으면 아래의 함수가 호출된다.

* Publisher 프로토콜 중
func receive<S: Subscriber>(subscriber: S)

2. subscription 을 생성하고 Subscriber 에게 전달해준다.

let subscription = ...
subscriber.receive(subsctiption: subsctiption)

* Subscriber 프로토콜 중
func receive(subscription: Subscription)


3. subscriber 는 값을 요청한다. ( 이때 Subscriber.Demand 를 통해 원하는 수요를 정한다. )

func receive(subscription: Subscription) {
    subscription.request(.unlimited)
    ...
}

* Subscription 프로토콜중
func request(Subscriber.Demand)

* Demand 종류
Subscribers.Demand.none
Subscribers.Demand.unlimited
Subscribers.Demand.max(Int)

4. Subscription 은 값을 생성하고 subscriber 에게 값을 전달한다.


5. Subscription 은 값 전달이 완료되면 subscriber 에게 완료됨을 전달한다.

( Canncellable 프로토콜을 구현해서 작업을 도중에 중단할 수 있다. ) 


흐름을 보면 Publisher 는 사실 많은 일을 하지 않는다.

데이터 공급의 주요 역활은 Subscription 이 담당한다. Subscriber 는 데이터 받는 과정을 제어할수 있다.


여기까지 Publisher , Subscriber 에 대해 알아봤다. 

* Custom Publisher ( Subscriber ) 관련된 글은 따로 작성할 예정이다.



마침.


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari