iOS

RxSwift(1)

홍복치 2020. 4. 3. 23:37

KxCoding의 Mastering RxSwift 유투브를 보며 공부한 내용을 정리

 

RxSwift의 장점

[RxSwift Github 샘플 코드]

Observable.combineLatest(firstName.rx.text, lastName.rx.text) { $0 + " " + $1 } 
          .map { "Greetings, \($0)" } 
          .bind(to: greetingLabel.rx.text

- 두개의 텍스트 필드 값을 공백으로 연결 후 "Greetings"를 앞에 추가, 이를 Label에 출력

- 이를 rxSwift 없이 작성한다면 3라인의 코드로 불가

viewModel
    .rows
    .bind(to: resultsTableView.rx.items(cellIdentifier: "WikipediaSearchCell",
    cellType: WikipediaSearchCell.self)) { (_, viewModel, cell) in
        cell.title = viewModel.title
        cell.url = viewModel.url
    }
    .disposed(by: disposeBag)

- TableView와 CollectionView를 구현할 때도 전통적인 delegate를 구현하지 않고, 단순한 코드로 구현 가능

 

※ 모든 내용의 공통적 결론 : rxSwift를 사용하면 단순하고 직관적인 코드 작성 가능

 

Observer와 Observables

Observable

- 이벤트를 Observer에 전달

- 3가지 이벤트를 Observer에 전달

 

(1) Next

Observable에서 발생한 새로운 이벤트는 "Next"를 통해 Observe로 전달

이벤트에 값이 포함되어있다면 Next와 함께 전달 (Emission 배출, 방출이라고 함)

 

(2) Error

Error 발생 시 Observable에 "Error" 이벤트 전달

Observable의 LifeCycle에서 가장 마지막에 전달

Emission이라고 부르지 않고 Notification이라고 부름

 

(3) Completed

Observable이 정상적으로 종료 시 Observer로 전달

Observable의 LifeCycle에서 가장 마지막에 전달

Emission이라고 부르지 않고 Notification이라고 부름

 

 

Observer

- Observable을 감시(= 구독 Subscribe)하고 있다가 전달되는 이벤트를 처리

- Subscriber라고 하기도 함

 

 

Observable 생성

- create, from 연산자

 

create

- Observable의 동작을 직접 구현

- create : 하나의 클로저를 파라미터로 받음, Observer를 받아서 Disposable를 리턴

Observable<Int>.create {
    (observer) -> Disposable in
    observer.on(.next(0)) //next이벤트에 0을 받아 Observer에 전달
    observer.onNext(1) //1이 저장되어잇는 next이벤트 전달

    observer.onCompleted() //이 이후에 다른 이벤트 전달 불가, observable 종료
    return Disposable.create() //메모리 정리
}

 

from

- 배열에 담긴 인자를 순서대로 전달하고 완료 시 completed 이벤트 발생하는 Observable생성

Observable.from([0,1])

 

 

PublishSubject

- Subject로 전달되는 이벤트를 Observer로 전달하는 가장 기본적인 형태

- Observable인 동시에 Observer

- 이벤트를 전달받을 수 있고 다른 옵저버로 이벤트 전달 가능

- 이벤트 발생시 즉시 구독자에게 전달

- Subject가 최초로 생성되는 시점과 첫번째 구독 전 전달되는 이벤트는 그냥 사라짐

 

let disposeBag = DisposeBag()

enum MyError: Error 
{
case error
}

//구독 전 상태인 Subject
let subject = PublishSubject<String>()/

/사라지는 이벤트
subject.onNext("Hello")

//새로운 Observer 생성 후 Subject 구독
//publishSubject는 구독 이후에 전달되는 새로운 이벤트만 구독자로 전달
//"Hello"이벤트는 전달되지 않음

let o1 = subject.subscribe{ print(">>1",$0) }
o1.disposed(by: disposeBag)

//RxSwift라는 문자열을 담은 이벤트가 subject로 전달되고, subject는 구독자에게 전달
subject.onNext("RxSwift")

let o2 = subject.subscribe{ print(">>2", $0)}
o2.disposed(by: disposeBag)

//"Subject"이벤트는 이미 구독중인 o1과 o2에게 전달
subject.onNext("Subject")

//Completed는 o1, o2, o3에게 전달
subject.onCompleted()//Error는 o1, o2, o3에게 전달
//subject.onError(MyError.error)

let o3 = subject.subscribe{ print(">>3", $0) }
o3.disposed(by: disposeBag)