Apple에서 2019년 iOS 13 버전부터 사용 가능한 Combine Framework를 공개했다.
Combine Framework를 사용하기 위해서는 Publisher와 Subscriber로 데이터를 주고 받는 것에 대한 이해에서 부터 출발한다.
먼저 Publisher는 이벤트(혹은 값)를 전달하는 존재로 생각할 수 있고 , Subscriber는 Publisher가 내보낸 이벤트(혹은 값)를 수신하는 존재로 생각하면 된다 !
WWDC 2019에서 Apple은 Combine Framework의 흐름을 소개할 때 다음과 같이 소개한다~
먼저 Subscriber가 Publisher를 subscribe하기 전까지 Publisher는 대기 상태로 존재한다.(여기서 Publisher는 Publisher protocol을 준수하는 인스턴스)
Pusblisher의 subscribe(_:) 메서드의 전달인자로 Subscriber protocol을 준수하는 인스턴스를 전달하여 Pubulisher와 Subscriber를 연결한다.
Subscriber의 receive(subscription:) 메서드는 subscribe 요청을 인지하고 Publisher로 부터 Subscription 인스턴스를 전달 받는다.(Publisher-Subscriber 연결 완료!)
Subscriber는 전달 받은 Subscription의 reuest( _ : ) 메서드를 통해 Publisher의 값을 전달하라고 요청한다.
그럼 비로소 Publisher는 Subscriber에게 값과 오류 타입을 함께 전달한다.(오류가 발생하지 않으면 Never 오류 타입을 전달한다.)
Subscriber의 receive ( _ : )메서드는 Publisher로 부터 전달 받은 값을 처리한다.
만약 더 이상 Subscriber에게 전달할 값이 없으면 receiver(completion : )메서드를 통해 completion, 혹은 오류를 전달 받는다.
위의 과정에 사용된 메서드들은 Publisher의 protocol과 Subscriber의 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가 있다.
📍 Apple 문서에도 receive(subscriber:) 메서드 대신 위의 이미지에서 설명된 subscribe(_: )메서드를 사용할 것을 권장하고 있다.
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>)
}