이번 포스트에서는 RxSwift에서 Observable을 생성할 수 있는 다양한 방법에 대해서 알아보려고 한다.
just()
는 하나의 항목(item)만을 방출하는 Observable을 생성하는 메서드이다. 따라서 항목(item)을 하나만 방출한 뒤 해당 Observable은 dispose된다.
사용 방법은 아래 코드와 같이 Observable
클래스의 just()
메소드에 방출하고자 하는 항목을 인자로 전달하여 생성할 수 있다.
import RxSwift
let observable = Observable<Int>.just(1)
observable.subscribe(
onNext: { item in
print(item)
}, onCompleted: {
print("onCompleted")
})
//1
//onCompleted
코드를 보면 Observable을 구독(subscribe) 하자마자 항목을 방출하는 것을 확인할 수 있으며 하나의 항목을 방출 직후 onCompleted
가 호출되는 것을 볼 수 있다.
한 가지 공식문서에서도 주의를 요하는 것은 Observable로 Optional 타입의 값으로
nil
이 전달 된다면nil
을 방출하는 Observable이 생성된다.
import RxSwift
let observable = Observable<Int?>.just(nil)
observable.subscribe(
onNext: { item in
print(item)
}, onCompleted: {
print("onCompleted")
})
//nil
//onCompleted
이 부분은 아무것도 방출하지 않는 Observable을 생성하는 것으로 혼동을 줄 수 있는데, 아무것도 방출하지 않는 Observable은 empty()
메서드로 생성할 수 있다.
empty()
메서드는 아무것도 방출하지 않는 Observable을 생성하는 메서드이다.
사용 방법은 아래와 같이 Observable
에 empty()
메서드를 사용하여 생성할 수 있으며 생성된 Observable을 구독(subscribe)하는 동시에 onCompleted
가 호출되어 즉시 dispose 되는 것을 확인할 수 있다.
import RxSwift
let observable = Observable<Any>.empty()
observable.subscribe(
onNext: { item in
print(item)
}, onCompleted: {
print("onCompleted")
}
)
//onCompleted
from()
은 just()
와 반대로 여러 개의 항목을 방출할 수 있는 Observable로 인자로 배열을 전달받아 배열의 내부 요소를 하나씩 방출하는 Observable이다.
사용 방법은 아래와 같이 Observable
클래스에서 제공하는 from()
메서드에 전달인자로 배열을 전달하여 생성할 수 있다.
let observable = Observable<Int>.from([1, 2, 3, 4, 5])
observable.subscribe(
onNext: { item in
print(item)
}, onCompleted: {
print("onCompleted")
})
//1
//2
//3
//4
//5
//onCompleted
마찬가지로 배열의 내부 요소를 하나씩 방출한 뒤, 내부 요소가 모두 방출되었을 때 onCompleted
가 호출되며 해당 Observable은 dispose 된다.
create()
메서드는 위에서 본 다른 메서드들과는 다르게 메서드의 전달인자로 Observer를 파라미터로 전달받는 함수(클로저)를 전달 받아 Observable을 생성한다. 함수의 파라미터로 Observer를 전달 받기 때문에 사용자가 입맛에 맛게 onNext
, onCompleted
, onError
함수를 적절한 시기에 호출하여 사용할 수 있으며 전달된 함수가 종료 되기 전에 최소 1회 onCompleted
혹은 onError
함수를 호출해야 한다.
사용 방법은 아래의 코드와 같이 함수(클로저)로 전달된 observer
의 onNext()
메서드를 통해 원하는 시점에, 원하는 값을, 원하는 횟수만큼 값을 방출할 수 있다. onCompleted()
또는 onError()
또한 특정 시점에 호출하여 Observable을 원하는 시점에 dispose할 수도 있다.
import RxSwift
let observable = Observable<String>.create { observer in
observer.onNext("안녕하세요!")
observer.onNext("반갑습니다!")
observer.onCompleted()
observer.onNext("다음에 또 만나요!")
return Disposables.create()
}
observable.subscribe(
onNext: { item in
print(item)
}, onCompleted: {
print("onCompleted")
}
)
//안녕하세요!
//반갑습니다!
//onCompleted
create()
메서드를 통해 생성한 Observable을 사용할때 주의할 점을 다시 짚어보면, 함수(클로저)가 종료 되기 전에는 onComplted()
혹은 onError()
중 반드시 하나의 메서드가 호출되어야 하며 onComplted()
혹은 onError()
가 호출된 뒤에 Observable은 dispose 되었기 때문에 다른 메서드가 호출 되어도 해당 호출은 값을 방출하지 않는다.
위의 예시 코드에서도 onCompleted()
호출 뒤에 호출된 onNext()
메서드는 값을 방출하지 않은 것을 볼 수 있다.
마지막으로 onComplted()
혹은 onError()
가 호출된 후에 Disposables.create()
를 호출하여 반환하고 있는데, 반환하는 값이 무엇인지 살펴보자.
onComplted()
혹은 onError()
가 호출된 뒤에 Observable은 이미 dispose된 상태이다. 따라서 dispose된 상태에서는 다른 작업을 수행할 수 없기 때문에 명목상 Disposable 타입의 값을 반환하는 것으로 추측되며, RxSwift 라이브러리 내부에 create()
함수의 정의를 찾아보아도 아래와 같이 dispose 될때 아무것도 하지 않는 Disposable이라고 주석으로 설명 되어 있다.
extension Disposables {
/**
Creates a disposable that does nothing on disposal.
*/
static public func create() -> Disposable { NopDisposable.noOp }
}
이외에도 더 많은 Observable에 대한 정보는 공식 문서를 참고하는데 도움이 될 수 있다.