애플사이다의 iOS 개발 일지

[Combine] 기본 원리 - Apple이 만든 RxSwift를 이해해보자 (1/3) 본문

iOS

[Combine] 기본 원리 - Apple이 만든 RxSwift를 이해해보자 (1/3)

Applecider 2024. 1. 21. 15:06

최근 RxSwift를 Combine으로 전환하면서

Combine의 원리에 대해 자세히 알아봤다.

 

Combine 공식문서Kodeco의 Combine 자료가 큰 도움이 되었다.

 

개인적으로 Combine+UIKit 조합은 좋지 않은지, 꼭 SwiftUI와 함께 써야 하는지 궁금했다.

결론적으로 Combine이 first-party라서 더 안전하고, 성능이 좋기 때문에
그리고 UIKit에서 사용할 수 있는 API가 많이 나왔기 때문에 (assign 등등)
Combine+UIKit 조합도 괜찮다!! 라는 답을 얻었다.

 

Combine은 비동기 처리를 쉽게 해주는 도구이므로

네트워크 layer, 새로 구현하는 화면 등 프로젝트 일부에만 사용해도 괜찮으니

여러 시도를 해보는 게 좋은 것 같다.

 

Combine+UIKit 사용 예시도 다음에 포스팅할 예정이다.


먼저 간단히 표로 RxSwift와 Combine을 비교해보자.
Rxswift/Combine Cheatsheet을 자주 참고했다.

 

RxSwift에서 제공하지 않는 기능은 CombineExt 라이브러리를 활용한다. (ex. CurrentValueRelay 등)

이제 Combine 관련 커뮤니티도 제법 커졌다.

  RxSwift Combine
Framework Consumption Third-party First-party
Maintained by Open-Source / Community Apple / Community (커뮤니티 커짐)
     
     
던지는 애 Observable AnyPublisher
받는 애 Observer AnySubscriber
둘다 하는 애
(초기값 없음)
PublishSubject
- value, error, completed 던짐
PassthroughSubject
- value, error, finish 던짐
둘다 하는 애 (초기값 있음) BehaviorSubject CurrentValueSubject
  Single *Future (Deffered)
     
구독 .subscribe .sink or .assign
버리기 .disposed(by: disposeBag) .store(in: &cancellables)
     
스레드 전환
(down only)
observeOn receiveOn(on:)
스레드 전환 SubscribeOn
(up & down)
*Subscribe(on:)
(down only)
기타 공통 Operator just, combineLatest, zip, debounce … - 대부분 동일하게 있음
  merge(A,B,C) A.merge(with: B,C)
  do handleEvents
  skip dropFirst
  take prefix
  valueChanged removeDuplicates
     
없는거 BehaviorRelay
/PublishRelay


*CombineExt
CurrentValueRelay
  .asObservable *직접 구현
ReadOnly/CurrentValuePublisher

1. Introduction

Combine이 등장하기 전에 비동기 처리를 어떻게 했을까?

NotificationCenter, delegate pattern, Grand Central Dispatch (or Operations), Closures, Timer 등이 있다.

 

이제 위의 모든 기능은 Combine으로 통합하여 구현할 수 있다.

2. Combine Basics

Combine framework 공식문서를 열면 가장 먼저 보이는 문장이다.

비동기 이벤트, 선언적, publishers, subscribers라는 단어가 키워드임을 알 수 있다.

The Combine framework provides a declarative Swift API for processing values over time.
These values can represent many kinds of asynchronous events.

Combine declares publishers to expose values that can change over time, and 
subscribers to receive those values from the publishers.

 

이제 Combine의 3개 주요 요소인 Publishers, Operators, Subscribers를 보자.

1) Publishers

  • Subscribers에게 값을 방출한다.
  • 3개 종류의 이벤트를 방출할 수 있다. 그리고 한 번 complete 되면 (성공이든 실패든) 더 이상 emit하지 않는다.
    (1) Output
    (2) successful completion
    (3) Failure  안 함
  • error handling 기능을 기본 제공한다.
    Publisher protocol은 2개 타입에 대한 Generic 타입이다.
    (1) Publisher.Output : output 값의 타입 (ex. Int)
    (2) Publisher.Failure : 실패 시 publisher가 throw 하는 error 타입
    *만약 publisher가 절대 실패하지 않으면 Never 타입을 사용한다.

2) Operators

  • Publisher protocol에 선언된 메서드이며, 동일하거나 새로운 publisher를 반환한다.
  • highly decoupled/composable하다.
  • 항상 input 및 output을 가지며, 흔히 upstream/downstream라고 불린다.

3) Subscribers   

  • 방출된 output 또는 completion events를 받아서 뭔가를 한다.
  • 기본 제공되는 2개 종류의 subscribers가 있다.
    (1) sink subscriber : provide closures with your code that will receive output values and completions.
    (2) assign subscriber : without the need of custom code, bind the resulting output to some property on your data model or on a UI control to display the data directly on-screen via a key path.

 

그리고 문서를 읽다 보면 Subscriptions, Cancellable에 대한 언급이 많다.

4) Subscriptions

  • When you add a subscriber at the end of a subscription,
    it “activates” the publisher all the way at the beginning of the chain.
  • Subscriptions (pub sub mechanism)의 장점 : allow you to declare a chain of asynchronous events with their own custom code and error handling only once.

5) Cancellable

  • Cancellable을 통해 memory 관리가 자동으로 된다.
  • ex. ViewController의 프로퍼티로 Cancellable 또는 [AnyCancellable]을 들고 있도록 하는데,
    이 때문에 subscription의 lifespan을 쉽게 bind 할 수 있다.
    (VC dismiss/deinit → properties deinit → subscription cancel)

다음 포스팅에서는 Publishers, Subscribers, Cancellable Protocol에 대해 알아보고,

Subscriptions 과정을 뜯어볼 예정이다.

 

- Reference

Comments