
오늘은 프로젝트에서 사용했던, RxSwift 에서 PublishRelay, PublishSubject, BehaviorRelay, BehaviorSubject 에 관한 내용을 정리해보고자 한다.
관련 내용들은 진행했던 프로젝트에서 cmd+C,V 하여 사용했던 것을 토대로 개인적인 이해도를 정리하였으며, 관련 전문성은 현재로선 떨어지는 부분이지만 지금까지 이해한 정도를 정리하고, 추후 보완해 나갈 예정이다.
우선 현재까지 이해한 정도로 정리하자면
BehaviorRelay<T> 는 ObservableType이고 이는 ObservableConvertibleType 으로써 Observable<Element> 객체를 쉽게 들고 다니며 초기화, get, set, 변수로서 저장 용도로 사용할수 있는 클래스이다.
⇒ 결국 BehaviorSubject 라는 Observable<Element> 를 초기화, get, set, 변수로서 저장한다고 생각
PublishRelay<T> 역시 비슷한 개념인데, 살짝 다르다.
PublishRelay<T> 는 .accept를 통한 set 작업과 .asObservable의 Observable<Element> 형태로만 get 할수 있는 반면,
BehaviorRelay<T> 는 .accept를 통한 set 작업과 .asObservable의 Observable<Element> 형태로의 get 외에 .value 작업을 통해 Observable<Element> 의 Element 도 get 할 수 있다.
CocoaPods SwinjectAutoregistration 에 정리했던 ApiServiceType interface 를 토대로 사용 샘플코드를 정리해본다.
import RxSwift
protocol ApiServiceType {
var currentUser: User? { get }
var currentUserObservable: Observable<User?> { get }
// User 는 고객정보를 담은 객체
func requestLogin(password: String)
}
protocol interface 에서는 선언과 { get } 만!
아래 구현부 코드에서 프로토콜과 같이 사용한 코드를 정리한다.
final class ApiService: ApiServiceType {
private var _currentUser = BehaviorRelay<User?>(value: nil) // 초기화
// 원시 타입은 이런식으로 초기화 가능 → BehaviorRelay<Int>(value: 0)
var isLogged: Bool {
_currentUser.value != nil
}
var currentUser: User? {
_currentUser.value // value로 get
// 만약 _currentUser 가 PublishRelay 였다면 이런식의 get은 불가능하다.
}
var currentUserObservable: Observable<User?> {
_currentUser.asObservable()
}
func requestLogin(password: String) {
// 관련 서버에 사용자의 password입력을 받아, 사용자 정보를 받아왔다고 가정.
let user = User()
_currentUser.accept(user) // accept로 값 set
}
}
이런식으로 BehaviorRelay와 ApiServiceType 프로토콜 인터페이스와 구현부를 선언해놓으면
다른 클래스에서 SwinjectAutoregistration 을 통해 손쉽게 사용할 수 있다.
RIBs 아키텍처를 사용하는 경우의 사용 예제는 RIBs + ReactorKit 뼈대 정리를 참고하자.
import RxSwift
import UIKit
import SwinjectAutoregistration
class SampleViewController: UIViewController {
private var apiService: ApiServiceType
init() {
self.apiService = container ~> ApiServiceType.self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
if apiService.currentUser == nil {
// 비로그인 상태
} else {
// 로그인 상태
}
}
}
PublishRelay를 사용하는 예제는 추후 정리할 예정이다.
'iOS_RxSwift' 카테고리의 다른 글
| RxSwift 를 통한 UITableView 사용법에 대한 정리 (0) | 2022.02.01 |
|---|---|
| RxSwift + ReactorKit 에러 트래킹 Custom 방식에 대한 정리 (0) | 2022.01.14 |
| RxSwift ErrorTracker GitHub 코드 정리 (0) | 2022.01.11 |
| return Single<> 비동기 처리 (0) | 2022.01.11 |
| RxSwift ActivityIndicator GitHub 코드 정리 (0) | 2022.01.11 |