Swift - Combine

아토시스·2023년 12월 19일
0

Swift

목록 보기
14/14

Combine

Apple에서 2019년 iOS 13 버전부터 사용 가능한 Combine Framework를 공개했다.

Publisher 와 Subscriber


Combine Framework를 사용하기 위해서는 Publisher와 Subscriber로 데이터를 주고 받는 것에 대한 이해에서 부터 출발한다.

먼저 Publisher는 이벤트(혹은 값)를 전달하는 존재로 생각할 수 있고 , Subscriber는 Publisher가 내보낸 이벤트(혹은 값)를 수신하는 존재로 생각하면 된다 !

WWDC 2019에서 Apple은 Combine Framework의 흐름을 소개할 때 다음과 같이 소개한다~

먼저 Subscriber가 Publisher를 subscribe하기 전까지 Publisher는 대기 상태로 존재한다.(여기서 Publisher는 Publisher protocol을 준수하는 인스턴스)

  1. Pusblisher의 subscribe(_:) 메서드의 전달인자로 Subscriber protocol을 준수하는 인스턴스를 전달하여 Pubulisher와 Subscriber를 연결한다.

  2. Subscriber의 receive(subscription:) 메서드는 subscribe 요청을 인지하고 Publisher로 부터 Subscription 인스턴스를 전달 받는다.(Publisher-Subscriber 연결 완료!)

  3. Subscriber는 전달 받은 Subscription의 reuest( _ : ) 메서드를 통해 Publisher의 값을 전달하라고 요청한다.
    그럼 비로소 Publisher는 Subscriber에게 값과 오류 타입을 함께 전달한다.(오류가 발생하지 않으면 Never 오류 타입을 전달한다.)

  4. Subscriber의 receive ( _ : )메서드는 Publisher로 부터 전달 받은 값을 처리한다.

  5. 만약 더 이상 Subscriber에게 전달할 값이 없으면 receiver(completion : )메서드를 통해 completion, 혹은 오류를 전달 받는다.

위의 과정에 사용된 메서드들은 Publisher의 protocol과 Subscriber의 protocol에 선언 되어 있다.

Publisher Protocol



public protocol Publisher<Output, Failure> {

    /// The kind of values published by this publisher.
    associatedtype Output

    /// The kind of errors this publisher might publish.
    ///
    /// Use `Never` if this `Publisher` does not publish errors.
    associatedtype Failure : Error

    /// Attaches the specified subscriber to this publisher.
    ///
    /// Implementations of ``Publisher`` must implement this method.
    ///
    /// The provided implementation of ``Publisher/subscribe(_:)-4u8kn``calls this method.
    ///
    /// - Parameter subscriber: The subscriber to attach to this ``Publisher``, after which it can receive values.
    func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
}

Swift 문법 짚고 넘어가기 !!

protocol에는 일반적으로 함수에서 Generic을 선언 하듯이 Generic을 선언할 수 없다.
대신 protocol에서 Generic처럼 동적으로 타입을 지정할 수 있는 associaterdType placeholder가 있다.

추가 설명

  • Output 타입은 Publisher가 Subscriber에게 전달하는 값의 타입을 의미한다.
  • Failure Publisher가 Subscriber에게 전달할 오류 타입이다. Publisher가 Subscriber에게 전달할 때 오류가 발생하지 않으면 Never로 지정한다.
  • receive(subscriber : ) 메서드는 Subscriber protocol을 준수하는 인스턴스를 전달인자로 전달 받는다.

📍 Apple 문서에도 receive(subscriber:) 메서드 대신 위의 이미지에서 설명된 subscribe(_: )메서드를 사용할 것을 권장하고 있다.

Subscriber protocol


public protocol Subscriber<Input, Failure> : CustomCombineIdentifierConvertible {

    /// The kind of values this subscriber receives.
    associatedtype Input

    /// The kind of errors this subscriber might receive.
    ///
    /// Use `Never` if this `Subscriber` cannot receive errors.
    associatedtype Failure : Error

    /// Tells the subscriber that it has successfully subscribed to the publisher and may request items.
    ///
    /// Use the received ``Subscription`` to request items from the publisher.
    /// - Parameter subscription: A subscription that represents the connection between publisher and subscriber.
    func receive(subscription: Subscription)

    /// Tells the subscriber that the publisher has produced an element.
    ///
    /// - Parameter input: The published element.
    /// - Returns: A `Subscribers.Demand` instance indicating how many more elements the subscriber expects to receive.
    func receive(_ input: Self.Input) -> Subscribers.Demand

    /// Tells the subscriber that the publisher has completed publishing, either normally or with an error.
    ///
    /// - Parameter completion: A ``Subscribers/Completion`` case indicating whether publishing completed normally or with an error.
    func receive(completion: Subscribers.Completion<Self.Failure>)
}

추가 설명

  • Input은 Publisher로 부터 전달 받은 값의 타입을 의미한다.
  • Failure는 마찬가지로 오류 타입을 의미, 마찬가지로 오류를 전달 받지 않으면 Never 타입을 사용한다.
  • receive(subscription : ) 메서드는 Publisher로 부터 Subscription을 전달 받는다.
  • receive(_ input : )메서드는 Publisher로 부터 값을 전달 받는다. 반환 값은 앞으로 Publisher로 부터 얼마나 요소를 전달 받을 수 있는지를 나타낸다.
  • receive( completion : _ ) Publisher로 부터 completion 혹은 오류를 전달 받는다.
profile
오늘보다 더 나은 내일이 되길 바라며

0개의 댓글