What is Combine?
이벤트 처리 연산자를 결합하여 비동기 이벤트 처리를 사용자 지정합니다.
Combine 프레임워크는 앱이 이벤트를 처리하는 방식에 대한 선언적 접근 방식으로 제공합니다.
Combine을 채택하면 이벤트 처리 코드를 일원화(centralizing)하고 중첩 클로저 및 convention을 기반하는 콜백과 같은 번거로운 기술을 제거하여 코드를 더 쉽게 읽고 유지 관리 할 수 있습니다. 여기서 말하는 일원화는 특정 이벤트 소스에 대해 단일 처리 체인으로 만드는 걸 의미합니다. 체인의 각 부분은 이전 단계에서 받은 요소에 대해 고유한 작업을 수행하는 결합 연산자입니다.
Apple에서 비동기 프로그래밍을 개선하였고 몇 가지 메커니즘이 있습니다.
- NotificationCenter
: 디바이스의 방향을 변경하거나 키보드가 화면에 표시되거나 숨겨지는 등 이벤트가 발생할 때마다 코드 조각을 실행 - The delegate pattern
: 다른 객체를 대신하거나 다른 객체와 협력하여 작동하는 객체를 정의 - Grand Centeral Dispatch and Operations
: 작업의 실행을 추상화하여 직렬 대기열에서 순차적으로 실행되도록 코드를 예약하거나 우선순위가 다른 여러 대기열에서 여러 작업을 동시에 실행 가능 - Closures
: 코드에서 전달할 수 있는 분리된 코드 조각을 만들어 다른 객체가 실행 여부, 횟수, 컨택스트를 결정
대부분의 일반적인 코드는 일부 작업을 비동기적으로 수행하고 모든 UI 이벤트는 본질적으로 비동기적이기 때문에 앱 코드 전체가 어떤 실행될지 가정하는 것은 불가능합니다. 하지만 복잡할 뿐 좋은 비동기 프로그램을 작성하는 것은 가능합니다.
Combine API는 Foundation 프레임워크에 깊이 통합했기 때문에 Timer, NotificationCenter 그리고 Core Data와 같은 프레임워크에서 사용하고 있습니다. 또한 SwiftUI와 쉽게 통합되도록 설계되어 있습니다.
반응형 프로그래밍은 새로운 개념이 아닙니다. 2009년 Microsoft의 한 팀이 .NET용 Recative Extensions 라는 라이브러리를 출시하면서 등장했습니다. 2012년 Rx.NET 구현을 오픈 소스로 공개되면서 Rx 표준이 여러 가지 등장했습니다.
Combine은 Rx와는 다르지만 유사한 표준을 구현하는데, 이를 Reactive Streams라고 합니다.
This is Combine
Combine에서 핵심 요소는 3가지 입니다.
- publishers
- operators
- subscribers
Publishers
subscribers와 같은 하나 이상의 이해관계자에게 시간이 지남에 따라 값을 emit 할 수 있는 유형입니다.
모든 publishers는 3가지 유형의 이벤트를 emit 할 수 있습니다.
- 일반적인 Output 유형
- 성공적인 완료
- Failure 유형을 포함하는 완료
0개 이상의 값을 emit 할 수 있으며, 성공 또는 실패로 인해 완료된 경우 다른 이벤트는 emit 하지 않습니다.
시간에 따른 Int 값을 내보내는 publishers는 아래와 같습니다.
3가지 유형의 이벤트의 간단한 contract(계약)은 매우 보편적이어서 프로그램의 networking calls, 사용자의 제스처 그리고 데이터를 표시하는 등 모든 동적 데이터를 나타낼 수 있습니다. delegate 혹은 complition callback 등 작업을 publishers로 대신할 수 있습니다.
Publisher protocol에는 2가지 유형이 있습니다.
- Publisher.Output
: Int로 정해진 경우 String, Date와 같은 값으로 emit 불가 - Publisher.Failure
: publisher가 실패할 때 발생하는 유형으로 절대 실패할 수 없는 경우에는 Never를 사용
Operators
동일하거나 새로운 Publisher protocol에 선언된 메서드입니다. 여러 연산자를 차례로 호출하여 효과적으로 서로를 연결할 수 있습니다.
고도로 분리되거나 결합할 수 있습니다. 연사자의 출력이 다음 연산자의 입력 유형과 일치하지 않아도 맞출 수 있습니다.
추상화된 비동기 작업의 순서를 올바른 입력/출력 유형 및 기본 제공된 오류 처리와 함께 정의할 수 있습니다.
operators는 항상 upstream과 downstream이라는 input과 output이 존재하기에 상태 공유를 피할 수 있습니다.
비동기적으로 실행되는 어떤 코드도 작업 중인 데이터에 끼어들어 변경할 수 없습니다.
Subscribers
마지막으로 구독으로 끝이 나며, 모든 구독은 subscriber와 함께 끝납니다.
일반적으로 emit된 ouput 혹은 완료 이벤트를 수행합니다.
Combine은 데이터 stream을 간단하게 해주는 2가지 subscribers가 있습니다.
- sink
: 출력 값과 완료를 수신할 코드에 클로저를 제공 - assign
: 사용자 지정 코드 없이 결과 출력을 데이터 모델 또는 UI 속성으로 binding
데이터에 대한 다른 요구 사항이 있는 경우 publishers를 만드는 것보다 custom subscribers를 만드는 것이 훨씬 더 쉽습니다.
Subscriptions
subscription이 끝날 때 subscriber를 추가하면 체인의 시작 부분에서 publisher가 활성화됩니다.
잠재적으로 출력을 받을 구독자가 없는 경우 publisher는 어떤 값도 emit 하지 않습니다.
완전히 결합되면 subscription을 통해 전체 앱의 로직을 설명할 수 있으며, 일단 완료되면 데이터를 푸시하거나 가져오거나 다른 객체를 호출할 필요없이 모든 것을 실행하도록 할 수 있습니다.
특정 이벤트가 publisher를 깨울 때마다 비동기적으로 실행됩니다. 또한, Combine에서 제공되는 Cancellable protocol로 특별히 메모리 관리할 필요도 없습니다. 모든 시스템에 제공되는 subscribers는 해당 객체가 메모리가 해제할 때마다 전체 subscription이 취소되고 해당 리소스가 메로리에서 해제됩니다.
Combine benefit
기존의 방법으로 추상화를 직접 구축하는 것보다 더 편리하고 안전하며 효율적입니다.
- 시스템 수준에서 통합
- 버튼이나 제스처에 대해 지정될 코드를 operators를 통해 추상화
- publisher를 사용하여 비동기 작업 구성과 재사용성
- 새로운 operator를 만들 경우 Combine과 즉시 연결 가능
- 쉬워진 테스트
Architecture
Combine은 앱 구조에 영향을 미치는 프레임워크가 아닙니다. MVC, MVVM, VIPER 등에서 사용할 수 있습니다.
코드를 개선하고자 전부 교체할 필요가 없습니다. 데이터 모델을 변환하거나 네트워킹 계층을 조정하는 것으로 시작하거나 추가하는 새 코드에만 Combine을 적용할 수 있습니다.
MVC 아키텍처에서 Combine과 SwiftUI를 사용하게 된다면 두 가지가 한 공간에서 작동하기 때문에 C를 삭제하는 것이 합리적입니다.
'Language > Swift' 카테고리의 다른 글
[Swift] Reactive Programming Combine - 3: Transforming Operators (0) | 2024.05.08 |
---|---|
[Swift] Reactive Programming Combine - 2: Publishers & Subscribers (0) | 2024.05.04 |
[Swift] Protocol-Oriented Programming: POP (0) | 2024.04.30 |
UIActivityViewController 공유하는 그거 (0) | 2024.03.08 |
[Swift] 알고리즘을 대비한 메서드들 (0) | 2024.02.18 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!