티스토리 뷰
Publisher
시간이 지남에 따라 하나 이상의 값을 방출할 수 있는 Protocol 입니다.
public protocol Publisher {
associatedtype Output
associatedtype Failure : Error
func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
}
- Output: 내보내는 값의 타입
- Failure: 내보내는 에러의 타입 ( 단, Error 프로토콜 채택 필수)
- receive(subscriber:)
Subscription을 생성해서 Subscriber에게 값 전달 합니다.
이 때 이 Subscription이 실제적인 작업과 값 전달을 담당하게 됩니다.
즉 Publisher는 Subscription의 팩토리 객체라고 볼 수 있습니다.
Subscriber
Publiser에게 값이나 이벤트를 받을 수 있는 Protocol 입니다.
public protocol Subscriber : CustomCombineIdentifierConvertible {
associatedtype Input
associatedtype Failure : Error
func receive(subscription: Subscription)
func receive(_ input: Self.Input) -> Subscribers.Demand
func receive(completion: Subscribers.Completion<Self.Failure>)
}
- Input: Publisher로 부터 받는 값 타입
- Failure: Publisher로 부터 제공받을 에러 타입 ( 단, Error 프로토콜 채택 필수)
- receive(subscription:):
아까 얘기했던 Publisher에 receive(subscriber:)에서 호출 하는 메서드입니다.
즉 Subscription을 제공 받는 메서드가 됩니다.
이 때 전달받은 Subscription을 통해서 Subscriber가 이벤트를 요청하게 되는거죠 - receive(_:)
Subscription이 값을 만들어서 Subscriber에게 전달할 때 사용하는 메서드입니다.
또한 몇 개의 값을 더 받게 될 지 Subscription에게 알려주는 역할을 하게 됩니다. - receive(completion:)
Subscription이 정상적 또는 오류로 인해 종료되었음을 알리기위해 사용되는 메서드 입니다
Subscription
public protocol Subscription : Cancellable, CustomCombineIdentifierConvertible {
func request(_ demand: Subscribers.Demand)
}
Subscriber는 request(_:)을 호출하여 최대 몇개의 값을 받을 수 있는지 나타낼 수 있습니다.
즉 Subscriber가 Subscription을 처음 호출 할때 subscriber가 받으려는 최대 값 수를 지정하더라도 새 값을 받을떄 마다 조정이 가능하다는 이야기인거죠.
Flow?
위의 이야기를 요약해서 그림으로 표현해봤습니다.
Custom Subscriber
Publisher는 만들어야할게 많으니 Subscriber만 만들어봅시다.
가정해봅시다 지금 Publiser에서는 값이 하나씩 내려오고 있다고 말이죠.
class StringArraySubscriber: Subscriber { }
이렇게 만들어 두면 XCode에서 Fix를 누르면 Input과 Failure의 타입을 정하라고 나올껍니다.
각각 String과 Never로 만들어줍시다. Never로 하는 이유는 에러가 안나기 때문입니다.
class StringArraySubscriber: Subscriber {
typealias Input = String
typealias Failure = Never
}
이렇게하고 나면 이제 위에서 설명한 3개의 함수를 각각 구현해줘야합니다, 저는 아래처럼 구현했습니다.
let receiveValue: (Input) -> Void
let receiveCompletion: (Subscribers.Completion<Failure>) -> Void
init( receiveCompletion: @escaping (Subscribers.Completion<Failure>) -> Void,
receiveValue: @escaping ((Input) -> Void)) {
self.receiveCompletion = receiveCompletion
self.receiveValue = receiveValue
}
func receive(subscription: Subscription) {
subscription.request(.unlimited)
}
func receive(_ input: String) -> Subscribers.Demand {
receiveValue(input)
return .none
}
func receive(completion: Subscribers.Completion<Never>) {
receiveCompletion(completion)
}
자 이렇게 오늘은 Publisher와 Subscriber에 대해서 알아봤습니다.
처음엔 다소 어려운 개념이니 여러번 읽어보시는 걸 추천드립니다.
또한 마지막에 만들었던 Subscriber에서 Demand값을 조정해보시면 Demand 이해에 도움이 될 것 같습니다.
저는 처음에 이 Demand가 이해가 안되어서 고생했습니다.
그럼 글 마치겠습니다
제가 작성한 포스팅은 아래 링크를 참고했습니다.
https://jcsoohwancho.github.io/2020-01-20-Combine-시작하기(3)-Subscriber/
'Combine' 카테고리의 다른 글
[연산자 정리 001 ] collect, map, replaceNil, scan (0) | 2020.02.26 |
---|---|
Combine을 시작하기 전에 (0) | 2020.02.14 |
CombineLatest (0) | 2020.02.11 |
[Combine] Sequence (0) | 2019.12.20 |
[Combine]Just (0) | 2019.12.16 |
- Total
- Today
- Yesterday
- 스위프트
- 삨
- 콤바인
- 유니온파인드
- Queue
- 텔큐온
- programmers
- 현업이그리운
- Apple
- UIViewControllerRepresentable
- iOSCombine
- swift
- BBIK
- MVC
- 스위프트유아이
- combine
- SEQUENCE
- ios
- 스유
- 자료구조
- 알고리즘
- 스택뷰
- CombineLatest
- Just
- 결합연산자
- ErrorHandling
- AutoLayout
- compactMap
- replaceNil
- SwiftUI
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |