애플사이다의 iOS 개발 일지

[RxSwift] Bind, Driver, Relay - Observable/Subject 말고 다른 것도 써보자 본문

비전공자용 노력/개발 툴

[RxSwift] Bind, Driver, Relay - Observable/Subject 말고 다른 것도 써보자

Applecider 2023. 1. 29. 22:06

Swift 문법을 배우는 것과 RxSwift를 배우는 것은 큰 차이가 있었다.

Swift는 처음부터 차근차근 배워야 하지만

RxSwift는 활용 방식이나 관련된 Operator가 너무 다양해서 필요한 것을 잘 추려서 써야한다.

 

그래서 Rx를 배우는 데 많은 시행착오가 있었다.
ViewModel-ViewController를 binding 하는 기초 예제를 정리해보려고 한다. 언젠가는..

겨우 Observable, BehaviorSubject, PublishSubject를 잘 쓰게 된 이후로는 이것만 썼다.

 

그런데 Rx의 기능을 충분히 활용하고 있지 못한 것 같아서

그 다음 단계로 UI를 안전하게 처리하기 위한 Bind, Driver, Relay를 배웠는데 매우 유용했다.

이 내용을 간단히 소개해보려고 한다.


1. bind(to:)

binding할 때 순환참조를 방지한다.

코드를 줄일 수 있다.

RxCocoa의 기능이다. UI에다가 Rx 기능을 붙인 개념이다.

 

subscribe(onNext:) 대신 bind(to:)를 쓰면 되고,

self?.labelText.text = $0 형태 대신 label.rx.text 형태로 쓴다.

 

참고 - "bind를 쓰면 Main thread에서 실행하는 걸 보장한다"는 블로그 글이 있는데 잘못된 정보이다.
bind는 내부적으로 subscribe를 호출하기 때문이다.

public func bind(onNext: @escaping (Element) -> Void) -> Disposable {
    return self.subscribe(onNext: onNext, onError: { error in
        rxFatalErrorInDebug("Binding error: \(error)")
    })
}

2. Observable 대신 Driver

UI 특성상 stream이 끊기면 안된다.

서버가 일시적으로 불안정한 등의 예상치 못한 이유로 인해 stream이 끊길 수 있는데

버튼이 동작하지 않거나, 검색창에 검색어를 입력해도 아무 반응이 없는 문제가 발생한다.

*Google Books API를 활용해서 검색화면을 구현했을 때 간헐적으로 문제가 발생했다.

 

그래서 Driver는 error가 발생했을 때 임의 값으로 처리해서 stream을 유지해준다.

(매개변수 네이밍인 onErrorJustReturn이 매우 적절하다.)

subscribe(onNext:), bind(to:) 대신 drive()를 하면 된다.

 

그리고 자동으로 Main 스레드에서 처리하므로 UI 처리에 더욱 안전하다.

따라서 이제 observeOn(MainSceduler.instance)가 필요 없다.

3. Subject 대신 Relay

Subject도 마찬가지로 error가 발생해도 stream이 끊기지 않도록 해야 한다.

Relay는 Subject에서 error가 발생하면 무시해서 stream을 유지해준다.

 

Subject와 종류도 똑같다. BehaviorSubject 대신 BehaviorRelay를 사용하면 된다.

 

onError, onComplete이 발생하지 않는 개념이라서 무조건 받아들일 수 밖에 없다.

따라서 onNext() 대신 accept()를 쓴다.

 

 

- Reference

 

🍎 포스트가 도움이 되었다면, 공감🤍 / 구독🍹 / 공유🔗 / 댓글✏️ 로 응원해주세요. 감사합니다.

Comments