RxSwift 에서 Modern Concurrency 사용하기

Kanghoon
4 min readJan 9, 2022

--

오늘은 RxSwift 6.5 버전에 들어가는 Swift Modern Concurrency 지원에 대해서 알아보겠습니다.

기존 RxSwift

RxSwift 의 불편한 점 중 하나는 간단한 비동기 동작에도 subscribe 혹은 bind 를 작성해야 해서 불편하고 가독성이 떨어졌습니다.

escaping closure 를 활용하기 때문에 weak (약한참조) 를 자주 활용해야 하는 것도 단점으로 작용됐죠. (실수할 여지가 생김)

Modern Concurrency with RxSwift

최근 iOS 13 부터 사용할 수 있는 Modern Concurrency (async, await, actor …) 를 학습하면서.. 이를 어떻게 활용할 수 있을지, 기존의 RxSwift 코드와는 어떻게 융화시킬 수 있을지 여러 고민하고 있었습니다.

때마침 RxSwift 레포에서 유용한 기능이 추가된 것을 확인했습니다.

RxSwift 6.5 부터 Observable 및 여러 Reactive Unit 을 async operation 혹은 sequence 인 것처럼 기다릴 수 있고, 비동기 작업(async unit)을 Observable 로 변환할 수도 있습니다.

하나의 값을 반환하는 Trait 다루기

먼저 하나의 값을 반환하는 Trait 을 async await 을 사용해보겠습니다

Single, Maybe, Completable 은 위처럼 사용할 수 있습니다. 각 Trait 의 목적을 명확하게 나타내는 것 같아 사용하기 간편합니다.

이를 이용해 이전에 작성했던 기존 코드를 변경해보겠습니다.

훨씬 읽기 간편한 코드가 되었습니다.

Observable과 에러가 없는 Trait 다루기

Observable 과 에러가 없는 Driver, Signal 은 비슷하게 사용할 수 있습니다.

observable 은 에러가 발생할 수 있기에 AsyncThrowingStream<Int, Error> 타입을 반환합니다. 반면에 Driver 와 Signal 은 에러가 없는 AsyncStream<Int> 타입를 반환합니다.

이를 실제로 사용하면 아래처럼 작성할 수 있습니다.

위 코드를 사용한 예제
위 코드를 사용한 예제

AsyncSequence 를 활용해 Observable 코드를 사용할 수 있습니다. 에러가 없는 경우는 try 만 제거해주면 됩니다.

+ 버튼을 클릭할 때 relay 의 값을 1 씩 증가시키면 위처럼 동작합니다. 간단하죠!

Async Task 를 Observable 로 변형하기

Modern Concurrency 로 작성된 Task 를 Observable 로 변형하는건 간단합니다. 기존처럼 asObservable()을 활용하면 됩니다.

활용하기

위 변경은 여러 곳에서 활용이 가능하지만, 유닛 테스트에서 가장 쉽게 활용해 볼 수 있습니다.

기존 RxTest, RxBlocking 을 통해서 작성했던 테스트 코드를 async await 을 통해 쉽게 작성이 가능합니다.

마무리

이제는 Swift 에서 비동기 코드를 처리할 수 있는 방법이 정말 다양해졌습니다. (PromiseKit, RxSwift, Combine, Concurrency Model …)

RxSwift 를 주로 사용하던 프로젝트에서 어떤 방향으로 나아가면 좋을지 고민이 되는데, 여러 방면으로 사용해보면서 방향성을 잡아나가야 할 것 같습니다.

많은 회사들에서 다양한 방법을 사용하고 있을 것 같아 좋은 활용 사례가 있다면 댓글로 공유부탁드립니다.

--

--