본문 바로가기
RxSwift

[RxSwift] 곰튀김님의 RxSwift 4시간 끝내기 정리 - 3교시

by beansBin 2021. 11. 1.

1교시, 2교시는 곰튀김님이 분류하신것이 아닌 제가 임의로 끊어들은 것을 기준으로 함을 알립니다,,🚨

 

 

이번 교시 메인은 2교시에 RxCocoa 이용한 UI 관련 RxSwift 코드의 중복을 리팩토링하는 심화 과정이다.

 

 

Observable을 분리해서 변수에 저장하기

 : RxCocoa에서 UI 컴포넌트인 textField에 RxSwift를 적용하기 위해서는 idField.rx.text~ 와 같은 코드를 사용한다.
 .rx -> idField 를 reactive type으로 바꿔주고, .text -> Observable의 요소를 갖고 있는 control property를 내려보낸다. 
 => 즉 idField를 Observable로 만들어주는 것으로 이해했다.

이렇게 만들어진 Observable은 별도의 변수에 분리해서 저장이 가능하다.
아래 코드처럼 asObservable() 메소드로 해당 control property가 Observable임을 명확히 해준다면 가능하다.

        let idInputOb : Observable<String> = idField.rx.text.orEmpty.asObservable()
        let idValidOb = idInputOb.map(checkEmailValid)
        
        let pwInputOb : Observable<String> = pwField.rx.text.orEmpty.asObservable()
        let pwValidOb = pwInputOb.map(checkPasswordValid)​


 => idInputOb에서 Observable을 받아 orEmpty() 처리 후 저장하고, 연쇄적으로 idValidOb에서 idInputOb에서 처리된 값을 받아서 checkEmailValid를 mapping 시켜주는 것. 변수로 분리했지만, 연쇄적으로 스트림으로 연결이 된다.

이렇게 Observable을 분리시켜서 만들어두고, 나중에 필요한 시점에 subscribe() 시켜서 이벤트를 받아오면 된다.
그러니까 비유하자면, Observable을 만드는 것은 클래스와 같은 청사진에 해당하는 것이고, subscribe()하는 것은 인스턴스를 실제로 만들어 사용하는 것과 같다.


그러면 이제 만들어진 Observable인 idValidOb(그런데 이제 orEmpty도, email check도 완료된)를 subscribe해서 데이터를 받아오자.

 idValidOb.subscribe(onNext: { b in self.idValidView.isHidden = b})
            .disposed(by: disposeBag)
 pwValidOb.subscribe(onNext: { b in self.pwValidView.isHidden = b})
            .disposed(by: disposeBag)

 Observable.combineLatest(idValidOb, pwValidOb, resultSelector: { $0 && $1 })
       .subscribe(onNext: { b in self.loginButton.isEnabled = b})
       .disposed(by: disposeBag)

 => onNext()를 활용해서 id, pw 형식을 확인하고 combineLatest()를 사용하는 것은 동일하지만 코드는 훨씬 간결해졌다.

 

Subject

 : RxSwift의 5개의 요소 Observable, Operators, Scheduelr, Subject, Single 중에서 4번째로 중요한 Subject.

ReactiveX 공식 사이트에서 참고한 Subject의 개념


=> 그러니까 Subject는 observable과 observer의 역할을 모두 할 수 있으므로 Subscribe를 할 수 있는데, Observable은 여러 observer를 Subscribe 할 수 있는 차이점이 있는 것.
스스로 데이터를 발생시킬 수 있는 observable이다. 원래는 just, from에 가지고 있는 데이터를 넘겨줬는데, subject를 이용하면 나중에 데이터가 발생했을 때 외부에서 데이터를 넣어줄 수 있고 & subscribe()도 할 수 있는 것임.

 - Behavior Subject
 : subscribe() 되면 디폴트 값을 스트림에 전달한다. 이후 해당 스트림에 한번 더 subscribe() 되면 이후에 발생된 데이터를 그대로 전달한다.

 


 error가 발생하는 경우 이후 스트림도 연쇄적으로 종료가 된다.


 - Publish Subject
 : 가장 간단한 형태로, subscribe()될 때 default값을 넘겨주지 않으며, 이후 subscribe()가 발생하면 Behavior subject와 마찬 가지로 발생한 데이터를 스트림으로 넘겨준다.

마찬가지로에러가 발생하면 스트림은 연쇄적으로 종료가 된다.


 - Replay Subject
 : 디폴트값이 존재하지 않고, 두 번째 subscribe()이 발생하면 이전에 발생했던 데이터들을 모두 함께 내려보내는 subject이다.



 - Async Subject
 : 디폴트값이 존재하지 않고, completed()된 이후 직전 데이터를 stream으로 내려보낸다.



이 중 behaviorSubject를 코드에 적용시켜보면 다음과 같다.
BehaviorSubject를 외부에 변수로 만들어준다. 입력 값을 담을 공간을 만들어주는 것.

    let idInputText: BehaviorSubject<String> = BehaviorSubject(value: "")
    let idValid: BehaviorSubject<Bool> = BehaviorSubject(value: false)
    let pwInputText: BehaviorSubject<String> = BehaviorSubject(value: "")
    let pwValid: BehaviorSubject<Bool> = BehaviorSubject(value: false)

그리고 idValidOb를 subscribe()할 때! behaviorSubject인 idValid에서 새로운 stream이 생성되고, 여기서 발생한 b라는 데이터를 외부에 있는 behaviorSubject인 idValid에 데이터를 저장하는 것.!!



간단히 해서 연쇄적으로 stream을 만들어보면 input에 대해서는 다음과 같다.

outpu에 대해서는 다음과 같다. 중간에 저장된 것을 가져다가 subscribe하는 것.




댓글