[Swift] Combine 입문가하기1 — 구성요소

SwiftUI 강좌 번외편

Harry The Great
해리의 유목코딩
5 min readFeb 9, 2020

--

SwiftUI 시리즈에 Combine으로 네트워크 구현하기를 작성하다 Combine 입문하기로 급격하게 선회하여 작성하게 되었습니다. RxSwift나 Ractive Swift에 대해 잘 모르시는 분들도 쉽게 이해할 수 있도록 작성하였습니다.

Combine이란?

Combine을 찾아보면 선언형 프레임워크 함수형 프로그래밍, 비동기를 기반으로 한 리액티브 등등 어려운 말들이 많지만 간단히 이야기하면 시간의 흐름에 따라 발생하는 이벤트를 처리하기 위한 API라고 하겠습니다.

Combine은 발생한 이벤트에 대해 어떻게 가공하고 소비해줄지에 초점을 맞춥니다. 비동기와 관련한 코드를 작성할 때 사용하던 불필요한 보일러 플레이트를 줄여주며 런타임 오류를 효율적으로 처리할 수 있고 데이터의 제공자가 아닌 데이터 요청자 측에서 처리할 수 있습니다.

Combine을 이루는 3가지

Combine은 크게 Publisher, Operator, Subscriber로 이루어져 있습니다. 먼저 Operator에 대한 설명은 뒤로하고 Publisher와 Subscriber로만 도식화해보겠습니다. Subscriber로부터 데이터를 요청받으면 Publisher에서 데이터를 제공하고 중간에 Operator를 거쳐 Subscriber에게 전달됩니다. Rx 등에서 흔히 보아온 생성자-소비자 패턴과 유사합니다.

Publisher와 Subscriber가 서로 데이터를 주고받을 때는 항상 두 가지의 타입이 존재합니다. 먼저 Publisher 입장에서는 Output 타입과 Failure 타입이 존재합니다. 에러가 발생했을 경우 Failure 타입 그렇지 않다면 Output 타입을 전달합니다. 이 데이터를 받는 Subscriber는 Publisher의 output타입과 동일한 Input타입과, 그리고 동일한 Failure타입을 가져야 합니다.

Publisher

Publisher의 프로토콜을 살펴보면 언급한 것처럼 Output, Failure 타입이 존재하고 동일한 타입의 Subscriber을 receive 함수로 연결할 수 있습니다.

Subscriber

Pulbihser에서 Subsriber로 데이터를 전달하는 과정을 파이프라인이라고 하겠습니다. 파이프라인에서는 꼭 성공 타입과 실패 타입을 함께 명시해주어야 합니다. 생성자와 소비자의 타입이 다르다면 에러가 발생하게 됩니다.

가장 쉽게 시작하기

모든 예제는 Playground에서 바로 작성해볼 수 있습니다. 꼭 상단에 import Combine를 선언해주세요. Publisher에서 숫자 5라는 값을 발생시키고 Subscribe에서 5라는 값을 받는 예제입니다.

Just는 오직 하나의 값만을 출력하고 끝나게 되는 가장 단순한 형태의 Publisher로 Combine Framework에서 빌트인(Built-in) 형태로 제공하는 Publisher입니다. Just는 인자로 받는 값의 타입을 Output 타입으로 실패 타입은 항상 Never로 리턴합니다.
sink는 클로저 형태로 데이터를 받는 Subscriber입니다. Input 타입으로는 클로저로 받게 되는 데이터 값을 에러 타입으로는 Never를 받습니다.

Just는 오직 하나의 값만을 출력하고 끝나게되는 가장 단순한 형태의 Publisher로 Combine Framework에서 빌트인(Built-in)형태로 제공하는 Publisher입니다. Just는 인자로 받는 값의 타입을 Output 타입으로 실패타입은 항상 Never 로 리턴합니다.

sink는 클로저 형태로 데이터를 받는 Subscriber입니다. Input 타입으로는 클로저로 받게되는 데이터값을 에러타입으로는 Never를 받습니다.

Publsiher 중 ConnectablePublsiher 프로토콜을 준수하는 Publisher는 autoconnext를 이용하여 subsriber연결여부와 상관없이 미리 데이터를 발행시킬 수 있습니다. Rx에서 이야기하는 Hot/Cold와 유사한 개념입니다.

이번에는 하나의 데이터가 아닌 시퀀스를 갖는 데이터 스트림을 발행해보겠습니다.

sink부분이 조금 뚱뚱해졌습니다. sink에 receiveCompletion를 구현하여 데이터 스트림이 완료될 때 로그가 찍히도록 했습니다. provider 퍼블리셔는 1부터 10까지 데이터를 하나하나 발행하게 되고 sink로 연결될 때 구독(subscribe)이 시작됩니다.

//1
//2
//…생략
// 9
// 10
// 데이터의 전달이 끝났습니다.

데이터가 발행될 때마 receiveValue가 호출되고 데이터 스트림이 끝나게 되면 receiveCompletion이 호출합니다. receive 이전 과정에 대해서는 다음편에서 설명하겠습니다.

다음편

--

--

Harry The Great
해리의 유목코딩

Android & IOS Developer 😀 미디움 이외에 스니펫이나 디버그노트로 활용하는 https://www.harrymikoshi.com/ 블로그도 운영하고있습니다.