맨날 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를 통해 [ 몇 개의 값을 받을 것인지] [ 취소 여부 ] 를 결정 가능함
몇 개의 값을 받을 것인지
위와 같은 형태로 받는다.
unlimited
-> 제한 없이 무한대로 받는다.max(_ value: Int)
-> value 개수 만큼 받는다.none
-> 안 받는다.
subscription을 저장하여 추후에 수정도 가능하다.
취소 여부
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