티스토리 뷰

Combine

Combine ) ConnectablePublisher

Zedd0202 2020. 4. 26. 17:03
반응형

 

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

Combine도 계속 공부해야하는데..!!!! @_@

ConnectablePublisher는 그냥 눈에 띄길래...공부해보려고 합니다.

 

ConnectablePublisher

ConnectablePublisher은 프로토콜입니다! 아오 프로토콜 개많음

정의는 publication을 연결하고 취소하는 명시적인 방법을 제공하는 publisher.

네 뭐 ConnectablePublisher이라는 이름에서 볼 수 있듯이 뭔가를 연결할 수 있는 publisher인 것 같아요?

elements를 생성하기 전에, 추가 configuration 또는 setup을 수행해야하는 경우에 ConnectablePublisher를 사용하면 된대요

이 Publisher는 connect()를 호출할 때 까지 element를 생성하지 않는다고 합니다.

failure type이 Never인 모든 publisher로 부터

makeConnectable()을 사용하여 ConnectablePublisher를 만드세연

 

자 그럼 사용해봅시다.

이런 아주 평범est publisher와 subsciber가 있습니다. 

sink안에서 value를 print하고 있으니, hello\nworld가 출력되게 됩니다. 

저 평범한 publisher를 ConnectablePublisher로 만들어주겠습니다.

만드는 방법은 위에서 말했듯이 makeConnectable()을 호출하면 됩니다.

ㅇㅋ

자 makeConnectable()을 호출해주었습니다!

자 그럼 저걸 돌리면 hello\nworld가 나올까요!?

 

 

돌려보시면 아시겠지만, 아무것도 출력되지않아요!

왜냐하면..

ConnectablePublisher는 connect()를 호출할 때 까지 element를 생성하지 않는다...고 위에서 말했죠!?

위에서는 connect()가 호출되지 않았기 때문에 element가 생성되지 않고 있어요.

그럼 모다..? connect()를 호출해주쟈

자..connect를 호출해주었습니다..

그럼 hello\nworld가 출력되는 것을 보실 수 있습니다! 

 

autoconnect()라는 메소드도 있습니다.

이름에서 짐작이 가듯이..자동으로 연결해주는 친구같죠!?

맞습니다. 

connectable publisher와 연결하거나 연결을 끊는 프로세스를 자동화 할 수 있도록 해주는 친구입니다.

뭐 이런식으로 쓰면 당연히 hello\nworld가 출력이 되겠죠?

 


Q : sink밑에서, publisher.autoconnect()호출해도 되지?

A : 그러면 hello\nworld가 출력이 안되는 것을 볼 수 있습니다.

autoconnect()는 업스트림 publisher에 자동으로 연결하는 친구여서..

ㅇ이걸 sink다음에 해주면 안되는 것 같아요..!! 이 부분은 틀리다면 꼭 말해주세요. 제 추측임.


사실 뭐 우리가 멀쩡한 publisher에 makeConnectable() / autoconnect()를 호출 할 일이 있을까요..!?

 

먼저 간단한 예부터 보겠습니다.

 

1. 애초에 publisher가 ConnectablePublisher타입인경우

그 중 하나가 TimerPublisher인데요.

Timer.publish를 하게 되면,

지정한 time interval로 현재 날짜를 반복적으로 emit하는 TimerPublisher가 만들어집니다.

저 print문에는 그럼 현재 날짜가 나오겠네요.

하지만...!!!!!!! 

TimerPublisher는 ConnectablePublisher타입

== connect()를 호출하지 않으면 값을 생성하지 않음.

즉, 위 코드는 아무것도 출력하지 않습니다. 

이럴 때 autoconnect()를 호출하면 되겠죠!?

이제 현재 날짜가 잘 나오는 것을 볼 수 있습니당!!!

 

2. Hold Publishing

말 그대로 Publishing을 홀딩시키고 싶으면 ConnectablePublisher을 사용하면 됩니다. 

정의에 충실한..

시나리오를 생각해보겠습니다.

하나의 publisher가 있고, 그 publisher를 구독하는 구독자가 2개 이상이라고 생각해봅시다.

이 다중 구독자 시나리오는 경쟁조건을 만들 수 있는데요,

publisher가 두번째 구독자가 존재하기 전에 첫번째 구독자에게 element를 보낼 수 있습니다. 

URLSession.DataTaskPublisher가 있습니다.

URLSession.DataTaskPublisher와 subscriber1을 sink를 통해 연결시켜줍니다.

sink되는 순간 data task는 URL에서 데이터를 가져오기 시작합니다.

좀 이따가 subscriber2가 연결됩니다.

DataTaskPublisher가 두번째 구독자가 연결하기 전에 데이터 다운로드를 완료하면,

두번째 subsciber는 데이터는 놓치고 완료 이벤트만 받게 됩니다. 

이럴때 ConnectablePublisher를 사용하면 유용합니다.

출처 : https://developer.apple.com/documentation/combine/controlling_publishing_with_connectable_publishers

makeConnectable을 이용해 publisher를 ConnectablePublisher로 만들고, 

1초뒤에 subsciber2를 연결시키고

2초뒤에 connect()를 호출하여 publisher가 요소를 생성하게 했습니다.

이러면 subsciber1, subsciber2가 둘 다 연결됐다는 걸 보장할 수 있죠.

asyncAfter를 이용해 했다는게 맘에 걸리지만zzzzz 일단 이렇게 사용할 수 있다는것만..!! 

근데 은근히 유용할 것 같네요. 공부하길 잘했다는 생각이! 

틀린 부분 발견하시면 댓글 부탁드려요!

반응형

'Combine' 카테고리의 다른 글

Combine ) Operator (1) - Mapping Elements  (0) 2020.05.21
Combine ) multicast , share  (3) 2020.04.26
Combine + UIKit  (2) 2020.04.19
Combine (4) - Cancellable  (0) 2020.03.24
Combine (3) - Scheduler  (4) 2020.03.23