안녕하세요🐶
빈지식 채우기의 비니🙋🏻♂️입니다.
지난 글에서는 간단히 Combine에 대해 알아보았습니다.
.
간단히 요약하면 Apple에서 2019년에 만든 프레임워크로서,
RxSwift와 같이 비동기 프로그래밍을 간단하게 처리가 가능하다 입니다.
[Combine] Combine 이란?
안녕하세요🐶 빈지식 채우기의 비니🙋🏻♂️입니다. 요즘 RxSwift 공부를 통해 비동기 프로그래밍에 대해 블로그도 작성하고 있는데, First-Party 인 Combine 이라는 것이 있더라구요! . 마찬가지
beanistory.tistory.com
이번 포스팅에서는 지난 글에 이어 Publisher, Subscriber에 대해 알아보도록 하겠습니다.
1. 개요
Combine의 핵심은 전부 프로토콜로 이루어져있습니다.
크게 아래와 같이 5개로 확인할 수 있겠네용
- Publihser
- Subscriber
- Subject
- Scheduler
- Cancellable
일단 Publihser 와 Subscriber 그리고 Subscription의 흐름에 대해 먼저 알아보도록 하겠습니다.
이러한 흐름이 있는데 실제 예제를 통해 알아보도록 하겠습니다!
class IntSubscriber: Subscriber {
typealias Input = Int
typealias Failure = Never
// Publisher가 Subscription주면 호출됨
func receive(subscription: Subscription) { // (4)
subscription.request(.max(1)) // (5)
}
// Publisher가 주는 값을 처리
func receive(_ input: Int) -> Subscribers.Demand {
print("Received value : \(input)")
// Publisher에게 한 번 더 달라고 요청
return .max(1) // (5)
}
func receive(completion: Subscribers.Completion<Never>) {
print("Received completion : \(completion)") // (6)
}
}
class CombineTest {
func Test1(){
let intArray: [Int] = [1,2,3,4,5] // (1)
let intSubscriber = IntSubscriber() // (2)
intArray.publisher.subscribe(intSubscriber) // (3)
}
}
1. Int 가 요소인 Array 생성합니다.
2. IntSubscriber 클래스를 참조하는 Subscriber 생성합니다.
3. intSubscriber 가 intArray.publisher 에게 값을 요청하면 달라고 합니다. ( 흐름도 2번 내용 )
4. Publisher가 Subscription을 만들어서 receive 메서드를 통해 Subscriber에게 전달합니다. ( 흐름도 3번 내용 )
5. Subscriber은 request 메서드를 통해 Publisher에게 값을 달라고 합니다. ( 흐름도 4. 5번 내용 )
6. 더 이상 줄 값이 없으면 Completion Event를 전달합니다. ( 흐름도 6번 내용 )
흠.. 이해가 되시나요..?
저 또한 공부하는데 어려움을 많이 겪은 부분입니다 ㅠ.ㅠ
.
Publisher 와 Subscriber에 대해 더 자세히 알아보도록 하겠습니다.
2. Publisher
Publisher | Apple Developer Documentation
Declares that a type can transmit a sequence of values over time.
developer.apple.com
위에서 잠깐 언급했듯이, Publisher는 프로토콜 입니다.
언어 해석은 무언가를 발행 한다는 의미 같은데.. 정확한 정의는
1. 타입이 시간에 따라 일련의 값을 전송할 수 있음을 선언
2. Publihser는 하나 이상의 Subcriber 인스턴스에게 element를 제공
3. Publihser는 receive(subscriber:) 메소드를 구현해 Subscriber를 accept 함
.
흠.. 무슨 뜻이냐고요..?
지금 포스팅하고 있는 저도 갑자기 햇갈리네요 @.@
좀 더 자세히 알아보도록 하겠습니다.
.
.
만약 Publisher를 직접 구현하고자 한다면,
- Output
- Publisher가 생성할 수 있는 값의 타입
- Failure
- Publisher가 생성할 수 있는 Error 타입
- 만약 Error 타입을 생성하지 않는다면 Never 타입 설정
- receive(subscriber:)
- Publisher 자신을 Subscribe 하는 Subscriber를 받습니다.
이렇게 3가지는 구현을 반드시 해야합니다.
.
개요의 예제와 같이,
설명을 보면 receive를 반드시 호출하라고 하는데..
Subscriber가 Publisher의 Subscribe 메서드를 호출하면,
자신을 receive(subscriber:) 메서드를 통해 Publisher에게 알립니다.
.
무슨 말씀인지 모르겠다고요..? 저도요 ㅎㅎ 그니까! 결론은
.
Publisher는 자신을 Subscribe 한 Subcriber에게 값을 보내는 프로토콜
.
이라고 정리하면 될 것 같습니다.
3. Subscriber
Subscriber | Apple Developer Documentation
A protocol that declares a type that can receive input from a publisher.
developer.apple.com
Publihser와 마찬가지로 Subscriber 역시 프로토콜입니다.
Publihser로부터 Input을 받을 수 있는 타입을 선언하는 프로토콜
.
이것도 역시 바로 코드로 확인해보도록 하겠습니다.
위의 예제처럼 Intsubscriber를 만들었는데,
그때처럼 직접 구현을 하기 위해서는 아래와 같은 것들을 필수적으로 구현해야 합니다.
- Input
- Publisher에게 받는 값의 타입
- Failure
- Publisher에게 받는 Error 타입
- 수신하지 않을 경우, Never 타입 지정
- receive(subscription:)
- Publisher가 만들어주는 subscription을 받음
- receive(input:)
- Publisher가 주는 값을 받음
- Demand를 반환하는데 이는 값을 더 원하는지에 대한 여부
- receive(completion:)
- Publisher가 주는 completion event 를 받음
❗️여기서 주의❗️
Publisher 의 Output 과 Failure
Subscriber 의 Input 과 Failure
는 반드시 타입이 동일해야한다.
receive(input:) 의 경우 Demand 를 반환하는데 Demand 는 또 뭔가요..? 팍씌..
설명을 보면 Publisher에게 보낸 Request 횟수라고 한다.
즉 Subscriber가 Publisher 에게 값을 달라고 요청할 수 있는데 그런 요청의 휫수라고 할 수 있습니다.
// Publisher가 Subscription주면 호출됨
func receive(_ input: Int) -> Subscribers.Demand {
print("Received value: \(input)")
// Publisher에게 한 번 더 달라고 요청
return .max(1)
// Publisher에게 값 더 이상 안줘도 된다고 알림
// return .none
// Publisher에게 끝없이 값을 달라고 요청
// return .unlimited
}
위와 같이 .max(1)을 반환하면 한번 더 달라고 요청하는 것입니다.
4. Subscription
Subscription | Apple Developer Documentation
A protocol representing the connection of a subscriber to a publisher.
developer.apple.com
그럼 마지막으로 Publisher가 만들어서 Subscriber에게 준다고 했던 Subscription 에 대해 알아보도록 하겠습니다.
1. Publisher 와 Subscriber를 연결하는 프로토콜
2. Cancel 의 경우 Subscription 스레드부터 안전해야함
.
위에 예제에서는 이렇게 사용했었습니다!
// Publisher가 Subscription주면 호출됨
func receive(subscription: Subscription) {
subscription.request(.max(1))
}
- Publisher에게 받은 Subscripton의 request(demand:)를 호출하여 Publisher에게 값을 요청
- Demand는 Publisher에게 값을 몇번 더 달라고 요청
- 즉 Subscriber가 Publisher에게 값을 요청할 때 Subscription을 사용
또한 공식문서를 보면,
cancel을 하려면 Subscription 스레드부터 안전해야 한다고 되어 있습니다.
cancel을 할 수 있는 이유는 Subscription의 경우 Cancellable 프로토콜을 채택하고 있기 때문입니다.
Cancellable | Apple Developer Documentation
A protocol indicating that an activity or action supports cancellation.
developer.apple.com
실제 Cancellable의 프로토콜을 보면,
이렇게 Subscription에서 cancel()을 구현하지 않으면,
계속해서 Subscription이 Complete 될때까지 메모리에 남아있게 됩니다.
5. 정리
Publisher | Subscriber | Subscription | |
특징 | 요소값이나 Completion event를 Subscriber에게 전달 | Subscription을 통해 Publisher에게 값을 요청 | 1. Publisher와 Subscriber 사이를 연결 2. cancel()을 통해 취소할 수 있으며, 이때 호출될 클로저를 설정할 수 있음 |
이상으로 간단하게 Publisher, Subscriber에 대해 알아보았습니다.
감사합니다.
참고
'iOS📱 > Combine' 카테고리의 다른 글
[Combine] 다양한 Publisher 들 1 ( Just, Future, Deferred ) (0) | 2024.02.08 |
---|---|
[Combine] Combine 이란? (2) | 2024.01.26 |