티스토리 뷰

반응형

 

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

요즘 너무 정신이 없네요 ㅠㅜ!!!!!!! 

오늘부터 컴바인 오퍼레이터를 빠개볼거에요~~

 

오퍼레이터 일단 ㄱㅐ많은데..같은 섹션에 있는 친구들을 보다보면..

언젠가...다 볼 수 있겠지..

 

오늘은 Mapping Elements친구들입니다.

 

map

tryMap

flatMap

mapError

replaceNil

scan

tryScan

setFailureType

 

이렇게를 오늘 볼거에요!

map먼저 보도록 합시다.

 

map

Combine의 map은 Swift Standard Library의 map과 똑같다고 보면됨.

map은 upstream publisher의 모든 요소를 변환하는 친구입니다.

map은 간단하죠?! 

파라미터로 넣은 transform closure에 모든 요소가 들어가게 되고 해당 클로저를 수행한 새로운 element가 반환됩니다. 

 

tryMap

map이랑 비슷한데 앞에 try가 붙었죠

tryMap은 제공된 error-throwing closure를 사용하여 upstream publisher의 모든 요소를 변환하는 친구입니다.

tryMap같은 경우, 클로져가 오류를 발생하면 publish를 종료하게 됩니다.

자...tryMap을 쓴 예제입니다. map이랑 똑같죠!!? 다만, 

map과 다르게 tryMap의 transform안에서는 에러가 발생될 수 있습ㄴ디ㅏ. 

위 예제는 에러가 없이 무사히 넘어갔지만..에러가 있는 케이스를 만들어볼게요. 

자 이런 상황입니다! handleNumber가 에러를 던질 수 있게 만들어졌고, 만약 num이 nil이면 ZeddError을 던지게 해놨어요. 

1과 2까지는 nil이 아니니 잘 수행되지만, 그 다음에는 nil이 있죠!?

nil 만남 > ZeddError던짐 > tryMap이 에러 받음 > failure 발생하고 publish종료. 

가 됩니다. 

그러니 transform으로 넣은 closure가 에러를 던지면 tryMap을, 아니라면 map을 쓰면 됩니다.

 

flatMap

역시나 Swift Standard Library에 있는 flatMap과 기능은 유사합니다. 

정의는 upstream publisher의 모든 요소를 지정한 최대 publishers 수까지 새로운 publishers로 변환합니다.

이게 무슨소리일까요!! 지정한 최대 publishers라니..

flatMap은 map이나 tryMap처럼 transform closure을 넣지만

maxPublishers라는 것을 넣을 수 있습니다. 기본값은 Subscribers.Demand.unlimited입니다. 

일단, flatMap은 "새로운 publishers를 반환한다"를 주의깊게 봐야합니다. map이나 tryMap처럼 어떤 값을 반환하는것이 아니라!! publisher를 반환하는 거에요.

애플 예제가 정말 직관적이네요. 애플예제를 같이 보도록 합시다@!!

1. WeatherStation을 넣을 수 있는 PassthroughSubject를 만들고, stationID를 넣어서 send를 합니다. 

2. 위 PassthroughSubject를 구독하고 있기 때문에 1번에서 send를 하면 이 스트림에 들어오게 되겠죠?!

3. 호스트는 동일하고, stationID에 따라 호출하는 url이 다릅니다. 

4. 해당 url로 dataTaskPublisher를 만들어 리턴합니다. 

 

이해가시죠!? flatMap은 새로운 publisher를 반환하기 때문에 이렇게 해준거에요. 

그렇다면 

maxPulisher를 지정해줘볼게요. 

기본값은 unlimited라고 했죠? 그래서 위 예제처럼 몇개를 넣어도 상관이 없어요. 하지만

url은;;제 로컬서버에서 테스트하느라 저렇게 되었읍니다. 

이렇게 maxPublishers를 지정해줘봤습니다. maxPublishers를 max(1)로 지정하겠다는것은

(구독 한번 당) 최대 1개의 publisher만 만들어 내겠다~ 라는 의미로 보면 될 것 같아요!

그래서 결과는 총 3개를 send했지만, 1개만 결과를 반환합니다.

flatMap의 특징은 모든 publisher를 성공적으로 완료해도 전체 스트림이 완료되지 않아요!

하지만 새로운 publisher를 만들어내는데 실패하면 전체 스트림이 실패하게 됩니다.

위 예제에서는 URL로 만들 수 없는 string이 들어오면 에러가 나게 되고, 전체 스트림이 실패로 종료되게 됩니다.

하지만 그 외의 상황에서는 maxPublisher의 개수만큼 실행하고, 계속 스트림이 살아있는 상태라는거!

 

엄청 유용하게 쓰일 수 있을 것 같네요 ㅎ!!!

 

mapError 

간단합니다. upstream publisher의 모든 오류를 새로운 오류로 변환하는 친구에요.

아니 애플예제들 넘나 잘만들어 놓은 것ㅋ

에러를 내야하니, tryMap과 같이 쓴 걸 볼 수 있네요. tryMap안에서 DivisionByZeroError가 발생하지만, mapError가 머다?? 

"모든 오류를 새로운 오류로 변환"

위 예제에서는 MyGenericError로 바꿔버렸죠!! 

이것도 유용하게 쓸 수 있을 것 같아요...!!!

 

replaceNil

replace하다 / Nil을

응 개쉬워

스트림에 있는 nil element를 제공된 element로 바꿉니다. 

더 이상의 자세한 설명은 생략한다.

 

scan

closure에서 반환 한 마지막 값과 함께, 현재 요소를 closure에 제공하여 upstream publisher의 요소를 변환합니다.

"그 것"의 scan과 완벽하게 똑같군요...

처음에 초기값(initialResult)을 넣고, 해주고싶은 Operation?을 넣어주면 됩니다. 위 예제의 initialResult는 0이네요.

참고로 생략 안하고 걍 해보면

뭐 이런식

reduce도 같이 봐야하는거 아니야!? 하시겠지만, reduce는 다른 섹션에 있네요. reduce할 때 scan도 같이 언급할게요.

아무튼 scan은 operation의 과정에서 생긴 값들을 계속 publish한다고 보시면 됩니다. 

그래서 "0 1 3 6 10 15 "라는 값들이 나오고 있는것이죠! (reduce를 잠깐 언급하자면, reduce는 과정 중에 생긴 값들은 publish안하고 딱 15ㅂ만 (최종 결과) publish)

 

tryScan

이건 뭐 당연히 scan중에 에러가 생길 수 있다!?!? 뿌슝빠슝 

맞습니다. 애플 예제를 같이 볼게요!

1. initialResult가 10.

2. 10 + 1 / 1 = 11

3. 11 + 2 / 2 = 6(Int니까)

4. 6 + 3 / 3 = 3

5. 3 + 4 / 4 = 1

6. 1 + 5 / 5 = 1

7. 1 + 0 / 0 -> DivisionByZeroError발생. 

8. 스트림 failure로 종료.

이 되겠네요.

 

setFailureType

지정하다? / 실패 타입을

맞습니다.

정의는 upstream publisher가 선언한 failure type를 바꾸는 친구입니다.

이 친구는 Failure가 Never일때만 사용이 가능합니다. 

뭐 이런게 있다고 쳐봅시다. Failure Type이 Error죠? 이럴때는 setFailureType를 호출하지 못합니다.

하지만

pub1이나 pub2는 Failure타입이 더이상은..Never..이기 때문에 setFailureType를 호출할 수 있게 됩니다.

만약에 업스트림이 에러를 발생할 수 있는데 실패타입을 지정하고 싶다..? -> mapError쓰셈ㅎ

만약에 업스트림이 에러를 발생할 수 없는데 실패타입을 지정하고 싶다..? -> setFailureType쓰셈

 

애플 예제입니다.

위에서 말했듯이 pub1의 error type은 Never고, pub2의 error type은 Error입니다.

지금 두 publisher간의 error type이 일치하지 않죠?

그래서 만약 pu1에 combineLatest(pub2)를 해주게 되면 

이런 에러가 나게 됩니다!

그래서 combineLatest전에 setFailureType을 이용해 pub1의 errot type을 pub2의 error type으로 세팅해주는 작업을 해줬죠!

그래서 combineLatest(pub2)를 에러없이 호출 할 수 있게 됩니다.

 

Mapping Elements섹션에 있는것들은 다 봤네요..!!!!! 

남은 오퍼레이터들이 진짜 개많은데..다 볼 수 있을지는 모르겠지만..다 보는 것을 목표로 ㅎㅎㅎ..!!!

 

다음 글 읽으러가기

 

Combine ) Operator (2) - Filtering Elements

안녕하세요 :) Zedd입니다. 오늘은 요소를 필터링 하는 Combine Operator친구들을 공부해봅시다. Mapping Elements Operator 읽으러가기 Combine ) Operator (1) - Mapping Elements 안녕하세요 :) Zedd입니다. 요..

zeddios.tistory.com

 

반응형

'Combine' 카테고리의 다른 글

Combine ) Operator (3) - Reducing Elements  (0) 2020.06.05
Combine ) Operator (2) - Filtering Elements  (1) 2020.05.30
Combine ) multicast , share  (3) 2020.04.26
Combine ) ConnectablePublisher  (0) 2020.04.26
Combine + UIKit  (2) 2020.04.19