
프로젝트를 하면서 RxSwift 사용시 네트워크 요청에 따른 로딩바와 에러처리에 ActivityIndicator 와 ErrorTracker 를 공통으로 묶어서 유용하게 사용했던 코드를 정리해놓고자 한다.
import Foundation
import RxSwift
import RxCocoa
final class ErrorTracker: SharedSequenceConvertibleType {
typealias SharingStrategy = DriverSharingStrategy
private let _subject = PublishSubject<CustomedError>()
/* CustomedError 란 Error를 상속받는 Custom Error Model
return Single<> 정리글 참조
*/
func trackError<O: ObservableConvertibleType>(from source: O) -> Observable<O.Element> {
return source.asObservable().do(onError: onError)
}
func asSharedSequence() -> SharedSequence<SharingStrategy, CustomedError> {
return _subject.asObservable().asDriverOnErrorJustComplete()
}
func asObservable() -> Observable<CustomedError> {
return _subject.asObservable()
}
func onError(_ error: Error) {
if let error = error as? CustomedError {
_subject.onNext(error)
}
}
deinit {
_subject.onCompleted()
}
}
extension ObservableConvertibleType {
func trackError(_ errorTracker: ErrorTracker) -> Observable<Element> {
return errorTracker.trackError(from: self)
}
}
UIViewController 에서 ErrorTracker 를 호출할 경우 연동하여 사용하는 법도 같이 정리해둔다.
BaseViewController 에 대한 내용은 ActivityIndicator 정리 활용
/*
공통 UIViewController
*/
class CustomViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupRx()
}
func setupRx() {
// Way #1.
errorTracker.asObservable()
.subscribe(onNext: { [weak self] in
print($0.message)
// self?.openConfirmAlert($0.message)
}).disposed(by: disposeBag)
// Way #2.
errorTracker.asObservable()
.flatMap { [unowned self] in self.openConfirmAlert(msg: $0.message) }
.subscribe()
.disposed(by: disposeBag)
}
// 등등
}
BaseViewController 를 상속받은 UIViewController 에서는
아래 코드와 같이 trackError 할 경우 공통으로 에러처리가 가능하게 된다.
apiService에서 API 요청에 대한 에러가 났을 경우 CustomedError 모델에 맞는 에러모델로 변환하여 에러를 내려줬을 것이고,
우리가 사용한 errorTracker는 CustomedError에 대해서 ViewController에서 공통처리를 할 수 있다.
※ 하나의 ViewController에서 사용자의 이벤트에 따라 여러개의 api 요청을 할 수 있다.
이때 에러를 공통으로 처리할수도 있지만, 어떤 api의 경우 에러에 대해서 custom하게 후속처리를 진행해야하는 경우도 있다.
이때 사용하면 좋은 .catchError 와 Async Model 에 대해서 별도로 정리하겠다.
apiService.exampleLogin() // RxSwift Observable 요청
.trackActivity(self.activity) // RIBs 사용하는 경우 presenter.activity
.trackError(self.errorTracker) // RIBs 사용하는 경우 presenter.errorTracker
.subscribe(onNext: { [weak self] _ in
}).disposed(by: disposeBag)'iOS_RxSwift' 카테고리의 다른 글
| RxSwift 를 통한 UITableView 사용법에 대한 정리 (0) | 2022.02.01 |
|---|---|
| Subject, Relay 에 대한 활용 및 이해도 정리 (0) | 2022.01.24 |
| RxSwift + ReactorKit 에러 트래킹 Custom 방식에 대한 정리 (0) | 2022.01.14 |
| return Single<> 비동기 처리 (0) | 2022.01.11 |
| RxSwift ActivityIndicator GitHub 코드 정리 (0) | 2022.01.11 |