Combine - Subscriber

Combine - Subscriber

빠더너스 문상훈 짤 모음 / 남친짤, 킹받는짤, 웃긴짤 모음zip : 네이버 블로그

맨날 sink sink sink 만 쓰다가. 어? subscribe 함수는 무엇이죠?

-> Subscriber 를 구독하는 함수인건 아는데...

subscriber 어떻게 쓰더라 생각이 안나서 글 작성해봄 ㄱㄱ


swswimport Combine

class CustomSubscriber: Subscriber {
    // 0️⃣
    typealias Input = <#type#>
    typealias Failure = <#type#>

    // 1️⃣
    func receive(subscription: any Subscription) {
        <#code#>
    }

    // 2️⃣
    func receive(_ input: Input) -> Subscribers.Demand {
        <#code#>
    }

    // 3️⃣
    func receive(completion: Subscribers.Completion<Failure>) {
        <#code#>
    }
}

0️⃣ Input & Failure

Publisher에서 나온 Input 과 Failure Type과 같아야 한다.

Just(0)
    .subscribe(CustomSubscriber())

1️⃣ receive(subscription: )

Publisher에 subscribe를 하면 작동하는 함수

subscription을 통해서 Publisher를 통해 [ 몇 개의 값을 받을 것인지] [ 취소 여부 ] 를 결정 가능함

  1. 몇 개의 값을 받을 것인지

위와 같은 형태로 받는다.

  • unlimited -> 제한 없이 무한대로 받는다.

  • max(_ value: Int) -> value 개수 만큼 받는다.

  • none -> 안 받는다.

subscription을 저장하여 추후에 수정도 가능하다.

  1. 취소 여부

subscription.cancel() 을 통해서 취소가 가능하다.

2️⃣ receive(_ input: Input) -> Subscribers.Demand

Publisher를 통해서 값을 전달 받을 때 작동하는 함수

( 그래서 오류가 2번으로 나눠서 안내 해줌)

Subscribers.Demand 이 반환 값은 앞으로 받을 값을 수정 할 때 적용된다.

1️⃣에서 subscription에 적용 되었던 몇 개를 받을 지 결정된 값에 누적되어 계산된다.

-> 1️⃣에서 .max(3) 을 하고 2️⃣ 반환 값으로 .max(1) 을 하면 총 4(3+1)개의 값만 Publisher를 통해 전달 받는 것임

3️⃣ receive(completion: Subscribers.Completion<Failure>)

Publisher에서 send(completion: )을 통해 Publisher가 끝났음을 알려오면 작동하는 함수

Subscriber의 작동 횟수가 끝났을 때 동작하지 않음을 주의하자.

예시 코드

import Combine
import Foundation

@Observable class ContentViewModel {
    var number = 0
    var cancelable = Set<AnyCancellable>()
    var value = CurrentValueSubject<Int, Never>(35)
    let subscriber = CustomSubscriber()
    init() {
        subscriber.delegate = self

        value
            .subscribe(subscriber)
    }

    func test() {
        value.send(Int.random(in: -1000...1000))
    }

    func count() {
        value.send(completion: .finished)
    }
}

class CustomSubscriber: Subscriber {
    weak var delegate: ContentViewModel?
    var subscription: (any Subscription)?

    func receive(_ input: Input) -> Subscribers.Demand {
        print(input, "INPUT")
        delegate?.number = input
        return .none
    }

    func receive(completion: Subscribers.Completion<Failure>) {
        print("Complete")
    }

    typealias Input = Int

    typealias Failure = Never

    func receive(subscription: any Subscription) {
        print("Subscription")
        self.subscription = subscription
        subscription.request(.max(3))
    }

    func cancel() {
        subscription?.cancel()
    }
}

참고한 사이트

https://developer.apple.com/documentation/combine/subscriber

https://zeddios.tistory.com/925