RxSwift는 코드가 새로운 data에 반응하고 순차적이고 격리된 상태로 처리할 수 있도록하여 asynchronous 프로그램 개발을 단순화한다.
Cocoapod(코코아팟) 설치 및 사용 방법 을 참고하여 다음과 같이
pod 'RxSwift'
의존성을 추가한다.
RxSwift의 핵심은 observable 기반으로 한다. Observable은 구독할 수 있고 map, filter, flatMap 등과 같은 다른 Rx 연산자를 적용하여 확장할 수 있는 data 또는 event의 sequence이다. sequence라는 말을 본다면 observable과 동일한 의미이므로 같다고 생각하면 된다.
next: observable 또는 sequence는 value를 방출할 수 있는 기능이 있다. 즉, observable 구독자에게 값을 전달할 수 있다. 그 value는 정수, 문자열, 다른 객체 등 무엇이든 될 수 있다.
completed: 어떤 이벤트를 종료시키는 기능이 있다. 즉, observable 구독자에게 완료되었다고 전달할 수 있다.
error: 이벤트가 있을 때마다 혹은 sequence가 완료될 때마다 오류가 발생하는 것은 아니다. 따라서 이벤트 도중에 프로그램이 그 시점에서 포기할 수 있다. 즉, observable 구독자에게 에러를 알릴 수 있다.
Observable 클래스를 사용하여 Observable을 생성할 수 있다.
let observable = Observable.just(1)
단지 하나의 특정 요소를 포함하는 Observable을 생성한다. 이 경우에는 1이다.
이것을 실행하면 아무일도 일어나지 않는다. Why? observable은 만들었지만 observable을 구독하지 않기 때문.추후에 구독하는 방법에 대해 설명한다.
let observable2 = Observable.of(1,2,3)
let observable3 = Observable.of([1,2,3])
타입 추론을 이용하여 Observable을 생성한다. observable3은 observable2와 다르게 개별적인 Int 값이 아니라 단일 요소인 Int 배열에 대해 작동한다는 차이를 잊지 말자.
let observable4 = Observable.from([1,2,3,4,5])
배열의 개별적인 즉, 각각의 요소들을 emit하는 기능을 가진다.
Subscribe는 subscription을 create하고 Observable에 Observer를 연결해준다. 즉, Observer에 담긴 이벤트들을 방출하는 것이 subscribe 메서드를 사용하는 것이다.
Observable에 subscription을 create하는 방법은 다음과 같다.
observable3.subscribe { event in
if let element = event.element {
print(element)
}
}
observable4.subscribe { event in
if let element = event.element {
print(element)
}
}
결과
[1, 2, 3]
1
2
3
4
5
위 예시를 보면 of와 from의 차이를 확연히 알 수 있다.
of는 whole array 또는 다른 인자 전체에 observable을 create한다.
from은 whole array라기보다는 array의 각각의 독립적인 요소에 대해 observable을 create한다.
unwrap할 필요없이 다음과 같이 구현할 수도 있다.
observable4.subscribe(onNext: { element in
print(element)
})
subscription을 create할 때 우리에게 subscriber를 return해준다. 그 subscriber는 특정한 sequence를 항상 듣거나 관찰할 것이다. 따라서 우리는 그 subscriber의 dispose를 확실하게 할 필요가 있다. Why? 메모리 누수가 일어날 것이기 때문.
subscription4.dispose()
특정 subscription을 dispose하기 위해서 위와 같이 할 수 있다. dispose는 모든 observer와 방출된 resource에 대해서 subscribe을 해제한다.
이렇게 하면 성공적으로 subscription이 완료되었다는 의미이고 메모리 누수가 일어나지 않을 것이다.
하지만, 많은 subscription이 있다면 그에 따른 dispose를 해야 하고 때때로 까먹을 수도 있다.
So, dispose하는 다른 방법이 있다.
let disposeBag = DisposeBag()
Observable.of("A","B","C")
.subscribe {
print($0)
}.disposed(by: disposeBag)
결과
next(A)
next(B)
next(C)
completed
해제를 해야하는 subscribe이 여러개일 때 유용하다.
observation을 생성하는 또다른 방법이 create function이다. 클로저 형식이며 다양한 값(onNext, onCompleted, ...)을 생성할 수 있다.
Observable<String>.create { observer in
observer.onNext("A")
observer.onCompleted()
observer.onNext("?")
return Disposables.create()
}.subscribe(onNext: { print($0) }, onError: { print($0) }, onCompleted: { print("Completed") }, onDisposed: { print("Disposed" )})
.disposed(by: disposeBag)
결과
A
Completed
Disposed
observable의 create function을 사용할 때 disposable을 return해야한다.
왜 물음표는 출력되지 않을까? complete되면 절대로 그 이후의 next event가 call이 되지 않기 때문.