티스토리 뷰

Combine

Combine (1) - Publisher, Subscriber

Zedd0202 2020. 2. 25. 14:26
반응형

 

안녕하세요 :) Zedd입니다.

이번 휴가동안 SwiftUI를 좀 해볼라하는데 Combine모르면 이거 걍 노답임....

-> 휴가 끝나버렸죠? 2020년 되버렸죠??????;;

그래서 Combine공부..

 

Combine


 

Combine이 너무 핫했어서..그냥 "뭔지"는 아시는 분들은 많으실것 같긴 한데..!!

간단하게 설명하면 WWDC2019에서 처음 소개된 "프레임워크" 입니다.

 

Apple이 소개하는 Combine을 볼게요.

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

 

Combine | Apple Developer Documentation

A publisher that allows for recording a series of inputs and a completion, for later playback to each subscriber.

developer.apple.com

자 프레임워크인데 어떤 프레임워크냐..!!

 

Combine은 시간에 따라 값을 처리하기 위한 선언적(declarative) Swift API를 제공합니다.

이러한 값들은 많은 종류의 비동기 이벤트를 나타낼 수 있습니다. 

Combine은 publishers가 시간이 지남에 따라 변경될 수 있는 값을 expose하고, subscribers가 publisher로 부터 해당 값을 받도록 선언합니다. 

 

 

한줄 요약 ==  Apple에서 RxSwift를 만들어따..........ㅎ 맞자나 솔직히

 

Combine쓰면 좋은점 머임??

 


이벤트 처리 코드를 중앙 집중화(centralizing)하고

중첩된 closures 및 콜백과 같은 까다로운 기술을 제거하여

코드를 읽고 유지보수하기 쉽게 만든다.


 

 

제 생각에 Combine은....소개를 아무리 읽어봐야 직접 써보지않으면 전혀 의미가 없습니다.

 

제가 옛날에 RxSwift..Reactive programming의 정의만 보고 아니 이게 더ㅗ대체 뭐지?

아무리 읽어도 모르겠네...< 라고 생각했거든요.

뭐 찰떡같이 알아들으셨다면 다행..! 

 

아마 RxSwift를 프로젝트에서 써보신 분들은 아마 이해하기 더 쉬우실거에요!!

 

이렇게 말하면 제가 Combine을 "직접" 써보고, 막 산전수전 겪고 이 글을 쓰는 것 같지만

저도 단 한번도 써본적 없습니다...ㅎ..!!!!

 

그래서 이걸 정말 차근차근 봐야함..

시작해봅시다.

 

 

 

 

 

Combine의 핵심은 전부 프로토콜로..이루어진 것 같은 느낌을 받았어요. 

하나씩 볼건데, 이것도 목차를 하나 만듭시다.

 

제가 그냥;;; 큼직한 것들을 골라서 만들어볼게요.

 

  • Publisher

  • Subscriber

  • Subject 

  • Scheduler 

  • Cancellable

 

위 5개 전부 프로토콜입니다.

 

흠 글을 쓰다가..뭔가 RxSwift는 이런데, Combine에서는 이거다! 라는 식으로 글을 좀 썼다가...

뭔가 저는...RxSwift도 잘 못하는 상태라zzz이게 좀 위험하다? 싶다는 생각을 해서 다시 올라와서.......

이런 코멘트를 남깁니다. RxSwift와의 비교는 안할게요! :D

 

 

Publisher가 뭐고 Subscriber뭐고..이걸 하나씩 다 보면 좀 헷갈릴 것 같아서..

오늘은 Publisher위주로 보고싶은데, Publisher를 이해하려면 Subscriber도 알아야 합니다. 

 

 

Publisher


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

 

Publisher - Combine | Apple Developer Documentation

Available when Failure is Output.Failure and Output conforms to Publisher.

developer.apple.com

위에서 잠깐 언급했듯이, Publisher는 프로토콜입니다. 

 

뭔가 이름만 보면..발행?하는 그런 친구같죠.

정의는

 


타입이 시간에 따라 일련의 값을 전송(transmit) 할 수 있음을 선언합니다.

Publisher는 하나 이상의 Subscriber인스턴스에게 element를 제공합니다.

Publisher는 receive(subscriber:)메소드를 구현해 subscriber를  accept합니다. 


 

 

 

Subscriber


 

Subscriber도 역시나 프로토콜이구요.

정의는

 


Publisher로부터 input을 받을 수 있는 타입을 선언하는 프로토콜


 

 

Subscriber 인스턴스는

 

- Publisher의 element stream

- 그들의 relationship의 변경사항을 설명하는 life cycle 이벤트

 

를 받습니다.

 

 

자, 지금까지 Publisher와 Subscriber프로토콜에 대해 아주 간략하게 봤는데

감이 오시나요?

Publisher는 값을 주는애고, Subscriber는 Publisher에게 값을 받는애..라고 생각하면 될 것 같아요?

zzzzz감이 하나도 안와도..뭐 괜찮습니다. 

 

그럼 Publisher, Subscriber인스턴스를 만드는 방법에 대해 봅시다.

 

 

일단 Publisher를 만드는 방법이 

 

뭐 이렇게 있는 것 같아요..?

아 처음에 글 쓸 때 저 6개를 다 하나씩 봐야지!! 하고 글을 썼는데

다시 보니..이걸 지금 설명해봐야 아무도 이해를 못하겠다는 생각을 하게 됐어요.

 

오늘은 Publisher와 Subscriber가 어떤식으로 값을 주고 받는지를 중심으로만 알아볼게요.

Publisher에서 가장 쉬운 Just를 이용해서 해보겠습니다. 

 

Just

 

각 subscriber에게 output을 한번만(just once) 출력한 다음 완료하는 publisher.

위에서 말했던 "Publisher"라는 프로토콜을 채택한 Struct입니다. 

 

~ 생성 방법 ~

 

응 개쉬워~~

 

자 그럼 Publisher가 "Zedd"라는 String을 발행(?)했어요.

이 값을 받을 수 있는 Subscriber를 만들어야겠죠?

 

 

sink라는 메소드를 사용하면 됩니다.

 

This method creates the subscriber and immediately requests an unlimited number of values, prior to returning the subscriber.

 

sink 메소드는 subscriber를 만들고,

subscriber를 리턴하기 전에 즉시 unlimited number of values를 요청합니다.

 

sink는 아마 정말 자주보게 될 메소드...이지만 일단은 이것만 알고 갑시다.

subscriber를 만들어주는 메소드입니다!

 

 

publisher 선언부에 바로 sink를 호출해도 되지만..

sink가 "subscriber를 만들고"를 강조하고싶어서...이렇게 만들어봤습니다.

아 ㅠ 저는 subscriber인스턴스를 도대체 어케만들어!!! 하면서 좀 헤맸는데...sink가 만들어주는거였음ㅎ

 

이렇게 하면 바로 Pulisher에게 값을 요청하므로 Zedd가 출력이 되겠죠.

sink는 위 인터페이스말고

 

 

receiveCompletion도 있는 인터페이스도 있어요. 

 

 

Receive를 완료해따..뭐 그렇게 보면 될 것 같아요. 

출력해보면

처음에 Zedd를 출력하고 그다음에

finished를 출력합니다. 

 

좀 이해가 가시나요? 

Future, Deferred, Empty 이거 다썼는데 지우기 좀 아깝긴 한데 

제가 이 글을 읽는 사람이라면..

안읽을 것 같아 지웁니다.

 

 

 

 

 

 그리고 이제부터 할 이야기는 읽어도 되고 안읽어도 되고..

저같은 궁금증을 가지신 분들만 읽으셔도 될 듯 ㅎ

 

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

 

Subscriber - Combine | Apple Developer Documentation

Available when Input is Void.

developer.apple.com

 

Subscriber의 공식문서입니다.

 

 

 

You connect a subscriber to a publisher 

by calling the publisher’s subscribe(_:) method.

 

ㅇ ㅑ!!!!!!!!!!!!!!!!!!!!!!!!!
publisher의 subscribe메소드 호출하면 publihser를 subscriber에 연결해줄게;;

 

(sink도 모를 때의) Zedd : 아아- 그렇군- 

 

뭔데

1. 아니 도대체 어케하는거

2. 구글링

3. 아니 왜 다들 sink로 하지? sink얘는 뭔데..subscribe하래매..

 

 

그래서 찾아본 결과...

 

문서는 진짜 팩트 그 자체를 전달하고 있었을 뿐..

 

먼저 publisher의 값을 subscribe하는 방법?이 3가지라고 할 수 있습니다. 

 

1. subscribe메소드를 이용하던가

2. sink사용하던가

3. assign(to: on:)쓰덩가

 

1번을 보겠습니다. 

 

파라미터의 타입이 Subscriber인 것을 볼 수 있죠? Subscriber뭐랬음

ㅇㅇ

프로토콜

 

만들어줍니다. 

 

몇번이고 말하지만 Subscriber는 프로토콜.

요구하는 프로퍼티와 메소드가 있습니다.

 

Input이랑 Failure정의하셈

 

엥?
Input은 subscriber가 받을 값의 종류라고 생각하시면 됩니다.

저는 Just("Zedd")를 예제로 썼으니까..String으로 해줄게요. 

 

Failure는 subcriber가 받을 수 있는 error의 종류입니다.

subscriber가 error을 받을 수 없는 경우, Never를 쓰라고 되어있네요.

흠 저는 일단 더이상은...Never...를 써보겠습니다.

 

 

끝난게 아님

 

 

위에서 부터 1번 마지막이 3번이라고 하면

 

1. subscriber에게 publisher를 성공적으로 구독했음을 알리고 item을 요청할 수 있음

 

2. subscriber에게 publisher가 element를 생성했음을 알림

 

3. subscriber에게 publisher가 정상적으로 또는 오류로 publish를 완료했음을 알림

 

아하~~~!~~!

 

 

request가 뭐야

unlimited는 뭐야

.none은 뭐야

 

하나씩 볼게요. 

 

1번

 

1. subscriber에게 publisher를 성공적으로 구독했음을 알리고 item을 요청할 수 있음

 

자..이렇게 subscribe가 됐다고 쳐봅시다.

그럼 가장 먼저 1번이 불리겠죠?

"subscriber에게 publisher를 성공적으로 구독했음을 알리고"

+

item을 요청할 수 있다..고 합니다.

 

이 메소드의(1번) 파라미터의 타입은 Subscription이라는 "프로토콜"인데요. 

이 subscription은 publisher와 subscriber간의 연결을 나타내는 말그대로 "구독"이에요.

이 subscription을 사용해서 publisher에게 item을 요청해야합니다. 

Subscription프로토콜에는 request라는 메소드가 있는데요, 

 

이를 통해 subscriber로 부터 publisher에게 요청 할 item의 수를 지정 할 수 있습니다.

Subscribers.Demand타입입니다. 

 

Subscribers.Demand에는

 

- unlimited(무제한)

- max(최대 개수 제한)

- none(no elements. max(0)과 같음)

 

가 있습니다.

 

말로하니까 잘 모르겠죠. 코드로 봅시다.

unlimited은 무제한이니까..눈으로 확인하기가 힘드니 max를 보겠습니다.

 

Zedd와 제 요즘 최애..Terror Jr 딱 2개까지만 나온 것을 볼 수 있죠?

"응 완료야"는 출력이 안되는게 맞습니다.

 

왜인지는 감이 오시나요..!?!?!?

왜 "응 완료야"는 출력이 안됐을ㄲ ㅏ요~~

 

네 바로

Alan Walker와 Martin Garrix가 발행되지 않았기때문입니다.

만약

위 코드에서

 

이렇게만 하면 

출력은

 

응 구독 시작이야~

Zedd

Terror Jr

응 완료야 finished

 

가 되게 됩니다. 

아무튼 1번은 이해하셨죠!? XD..

 

2번으로 가봅시다.

 

 

 

print("\(input)"에서

위의 Zedd와 Terror Jr이 출력된거겠죠? 

 

리턴은..

아까 1번에서 본

 

Subscribers.Demand네요!

그럼 리턴이 

 

- unlimited(무제한)

- max(최대 개수 제한)

- none(no elements. max(0)과 같음)

 

이렇게 될 수 있다는 말이겠죠??

 

이 리턴은 무엇을 의미하느냐?

subscriber가 받을 것으로 예상되는 element수를 나타냅니다!!!

 

흠 근데 잘 모르겠는게

2번에서 none으로 하면 

 

응 구독 시작이야~

Zedd

Terror Jr

 

ㅎ고 완료는 안됐었잖아요. (더 발행될 게 있으니까)

근데 max(1)이나 unlimited로 하면

 

응 구독 시작이야~

Zedd

Terror Jr

Alan Walker

Martin Garrix

응 완료야 finished

 

이런 결과가 나오네요..

ㅇ왜그러지??

 

제가 참고하면서 보고 있는 사이트에서는 .none을 리턴한다는게

"새로운 값을 받을 때 이 publisher의 demand를 변경하고 싶지 않음을 의미"

 

아 그럼 처음 1번에서 지정해준 demand를 변경하는건가..?

 

근데 해보면 그건 또 아닌데...

이거 정확히 아시는 분은...댓글로 알려주시면 정말 감사하겠습니다..OTL

 

음 만약에 demand를 변경한다는 의미라면

 

1번에서 max(1)을 리턴하고

2번에서 max(2)를 리턴한다면

 

응 구독 시작이야~

Zedd

Terror Jr

 

로 나와야하는거 아니에요..!? 

애초에 정의가 "subscriber가 받을 것으로 예상되는 element수"라며..

 

응 구독 시작이야~

Zedd

Terror Jr

Alan Walker

Martin Garrix

응 완료야 finished

 

왜 이렇게 나오는지 궁금..

 

 

왜 이렇게 나오는지 정리해봤습니다. 

아래 글을 참고해주세요!

https://zeddios.tistory.com/966

 

Combine (1-1) - Subcribers.Demand

안녕하세요 :) Zedd입니다. https://zeddios.tistory.com/925 Combine (1) - Publisher, Subscriber 안녕하세요 :) Zedd입니다. 이번 휴가동안 SwiftUI를 좀 해볼라하는데 Combine모르면 이거 걍 노답임.... -> 휴..

zeddios.tistory.com

 

 

그리고 마지막 3번!

 

뭐 별다른거 없자나요

완료임. 

 

출처 https://developer.apple.com/videos/play/wwdc2019/722/

이런식으로 Publisher와 Subscriber간의 통신(?)이 이루어지나 봅니다..

근데 receive(input)이 지금 여러번 불리자나 

그럼 여기서는(2번에서는) none을 제외하고 max(N)이나 unlimited나 똑같은거 아님...?

@_@ 헷갈려

 

ㅇ ㅏ무튼 이렇게 개고생하면서 subscriber를 만들 수 있긴 한데

Apple : sink만들어놨음 ㅋㅋ

 

...

 

 

참고 

https://www.donnywals.com/understanding-combines-publishers-and-subscribers/

 

Understanding Combine’s publishers and subscribers – Donny Wals

Learn how publishers, subscribers, and subscriptions work in this post. You will learn how to create your own subscribers and publishers in Combine.

www.donnywals.com

 

반응형

'Combine' 카테고리의 다른 글

Combine + UIKit  (2) 2020.04.19
Combine (4) - Cancellable  (0) 2020.03.24
Combine (3) - Scheduler  (4) 2020.03.23
Combine (2) - Subject  (0) 2020.02.29
Combine (1-1) - Subcribers.Demand  (0) 2020.02.26