안녕하세요 iOS 개발자 루크입니다
Combine…. 요 요망한 녀석… 이번엔 정말 정복해 보려고합니다
Combine 이란?
Reactive Programming 기반의 비동기 처리 프레임워크
Reactive Programming 이란?
비동기적인 이벤트를 하나의 stream 으로 묶어 관리하는 프로그래밍 패러다임.
iOS 개발자들은 기존에 비동기 처리를 위해 아래와 같이
•
Timers
•
NotificationCenter
•
Delegates
•
Operations
•
GCD
•
Closure callbacks
매우 다양한 도구를 사용했었다고 한다
뭘써야 적합할지 매번 고민했어야 했는데,
Combine 은 이러한 tool 들 중 어떠한 코드를 사용해야할 지에 대한 고민을 줄여줄 수 있다
즉, “아 몰랑 Combine 쓸래” 하면 된다는것.
더 좋은 점은 Combine이
Apple의 여타 프레임워크들과 굉장히 잘 맞아 떨어진다는 점이다.
특히! SwiftUI 그 이유는 다른 포스팅에서 다루겠습니다
Combine Basic
컴바인에는 주인공이 3명있다.
•
Publisher
•
Subscriber
•
Operator
물론 얘네 말고도 등장인물이 더 많지만, 일단 얘네들이 핵심인물이다. 기억하자
Publisher 란?
Publisher란 시간에 따라 이벤트를 발행할 수 있는 타입을 의미한다.
모든 Publisher 는 내부 로직과는 상관없이 3가지 타입의 이벤트를 발행할 수 있다
•
Publisher 의 Output 타입에 해당하는 값
•
successful completion
•
Publisher 의 Failure 타입에 해당하는 에러를 가진 completion
publisher 는 이벤트를 발행하지 않을 수도 있고
여러개의 이벤트를 발행할 수도 있다.
위 그림에서 Publsher<Int, Never> 는 시간에 따라 Int 값을 발행하고 있다.
모든 발행이 성공적으로 완수되어 마지막에
successful stream completion 이 발행되는 모습또한 볼 수 있다.
이처럼 publisher 의 3가지 발행가능한 이벤트는 거의 모든 동적 데이터 타입에 적용이 가능한 걸 볼 수 있다.
즉, 우리는 모든 데이터 타입이 이미 Combine 의 Publisher 를 사용하고 있다고 말할 수 있는 것이다.
Publisher 의 가장 핵심 특징은
에러핸들링이 내장되어 있다는 점이다.
위 그림에서 본 Publsher<Int, Never> 와 같이
Publisher 프로토콜은 두개의 타입을 가진다.
•
Publisher.Output
Publisher 가 발행 하고자 하는 출력의 타입을 의미한다.
•
Publisher.Failure
Publisher 가 throw 할 수 있는 에러 타입을 의미한다.
에러를 발행하지 않는 Publisher 의 경우 Never 타입으로 지정해 주면된다.
Publisher 에 대한 설명은 다음 포스팅에서 다시 더 자세히 다루어 보겠다
Operator 란?
Publisher 프로토콜에 선언되어 있는 메서드. → Publisher 리턴
Publisher 에서 발행된 이벤트의 값을 핸들링하는 데 사용되는 코드 조각들을 의미한다.
퍼즐 조각 처럼 끼워 맞추어 여러개를 연달아 사용이 가능하며,
이는 UI 또는 local DB 에 데이터를 보내기 전 가공하는데 주로 사용되는 듯 하다.
오퍼레이터에는 두가지 중요한 특징이 있다.
•
항상 input, output 이 존재한다는 점이다.
•
이를 upstrem downstream 이라고도 부른다.
Operator 는 데이터 처리에 초점이 맞추어져 있다.
앞선 체인에서 넘어온 결과물을 가공해 다음 체인으로 넘겨준다.
이렇게 Operator 로 데이터를 처리하게 되면 비동기적인 코드 조각들이 공유되는 하나의 데이터에 동시에 접근이 불가능해진다 → 즉 안정적으로 비동기 처리가 가능해진다.
Subscriber 란?
subcription 체인의 맨 마지막
일반적으로 발행된 결과물 또는 completion 이벤트들을 가지고 최종 작업을 해준다.
Combine 은 두개의 빌트인 subscriber 를 제공한다.
•
sink
◦
받은 결과 값을 처리하는 클로져를 붙여줄 수 있다.
◦
completion 이벤트에 대응하는 클로져를 붙여줄 수 있다.
•
assign
◦
어떠한 커스텀 코드 없이 결과 값을 데이터 모델이나 UI 의 프로퍼티에 bind 해준다.
이외에 data 와 관련해 다른 필요가 있다면 subscriber 는 커스터마이징 해서 사용하면 된다.
Subscriber 를 만드는 게 publisher 를 새로 만드는 것 보다 쉽다.
Subscription
subscription 의 마지막에 subscriber 를 붙이게 되면 publisher 가 체인을 활성화한다.
사용자 입력과 같은 이벤트가 fire 되면, timer 는 publisher 를 깨우게된다.
subscription 에 대해 구체적인 메모리 관리가 필요하지는 않다.
이는 Combine 의Cancellable 프로토콜 덕분이라고 한다.
빌트인 subscriber 인 sink, assgin 둘다 Cancellable 을 준수한다.
이는 두 subscriber 모두가 Cancellable 한 객체를 리턴한다는 뜻이다.
객체를 메모리에서 release 할 때마다, 전체 subscription 을 취소하고 메모리 자원을 할당 해제한다.
subscription 과 subscription 의 결과물의 수명은 쉽게 bind 할 수 있다.
사용자가 View Stack 을 dismiss 하면, 그와 관련된 프로퍼티들이 deinit 되고, 따라서 subscription 또한, 취소된다. (진짜 대박,,)
컴바인을 사용해야 하는 이유
•
시스템 수준에서 통합되어 있기 때문,
•
operator 로 분류된 코드들을 테스팅하기가 매우 용이하다.
•
operator 들을 퍼즐 조각처럼 뺐다 넣었다 할 수 있다.
•
안전하며, 편리하다.
컴바인은 앱 아키텍쳐에 영향을 주는 프레임워크가 아니다.
따라서 MVC 든, MVVM 이든 적용할 수 있다.
다만 MVVM 과 SwiftUI 와 매우 찰떡일뿐…