MapleStory Finger Point

[RxSwift] Cocoa Framework 판에 RxCocoa의 등장이라

2024. 4. 12. 22:09iOS Development/RxSwift

Cocoa Framework의 구성

  • Foundation: 기본적인 자료형과 메서드가 정의되어 있음
  • ApplicationKit(UIKit): 주로 UI 개발에 사용됨

 

RxCocoa

  • Cocoa 프레임워크(UI 컴포넌트와 각각의 속성, 이벤트 등)를 Rx로 감싸서 처리할 수 있도록 도와줌
  • ex. UISearchBar로 입력한 문구를 이용해 네트워크 통신을 하고 그 결과를 UITableView에 뿌려주는 기능
    • 서로 다른 클래스(UISearchBar, UITableView)에서 비동기적으로 발생한 값을 기존 애플 API가 제공하는 방식으로 조합하고 전달하려면 구현하기가 매우 까다로울 것
    • Rx를 이용하면 간단하고 명시적으로 작성 가능
let searchResults = searchBar.rx.text
    .distinctUntilChanged()
    .flatMapLatest {
        // 어떤 로직
    }
    
searchResults
    .bind(to: tableView.rx.items) {
        // cell 설정
    }
    .disposed(by: disposeBag)

 

Binder

  • 단방향 데이터 스트림
    • Binder는 데이터를 수신하기만 함(Observer의 역할만 함)
    • UI Binding에 사용
    • Error 이벤트를 받지 않음→ Error로 인해 시퀀스가 종료되고 더 이상의 이벤트가 전달되지 않으면 Binding된 UI가 업데이트 되지 않는 문제가 발생하기 때문!
    • Main Thread에서 실행되는 것을 보장

 

  • 앱의 데이터 흐름을 단순화하는 방법
  • ex. UITextField에 텍스트가 입력되면 UILabel을 업데이트하는 기능
textField.rx.text
    .observe(on: MainScheduler.instance)
    .subscribe(
        onNext: {
            label.text = $0
        }
    )
    .disposed(by: disposeBag)

// bind를 사용해서 간결해짐
textField.rx.text // Observable이 방출한 이벤트를 
    .bind(to: label.rx.text) // Observer에게 전달
    .disposed(by: disposeBag)

 

Trait

  • Error를 방출하지 않는 특별한 Observable(onNext만 취함)
  • 모든 과정은 Main Thread에서 이루어짐
  • 스트림 공유가 가능
    • 구독자가 생길 때마다 매번 스트림을 생성하는 것이 아닌 공유를 하기 때문에 리소스 낭비를 줄일 수 있음
  • asDriver나 asSignal 같은 메서드를 통해서 기존 Observable을 Driver, Signal로 변환 가능
    • Driver: 초기값 혹은 최신값 replay
    • Signal: 구독한 이후에 발생하는 값을 전달

 

Rx Extension

기존 Cocoa Framework의 객체들을 Rx 환경에서 사용할 수 있도록 커스텀하는 방법 제공

extension Reactive where Base: T {}
// extension으로 연산 프로퍼티 정의
extension Reactive where Base: UIView {
    var sizeToFit: Bind<Void> {
        return Binder(base) { base, _ in
            base.sizeToFit()
        }
    }
}

// 사용
Driver.just(Void())
    .drive(button.rx.sizeToFit)
    .disposed(by: disposeBag)