옵저버블 생성에 사용되는 연산자들을 정리한다.

# just, of, forms

just는 옵저버블 생성시 전달된 파라미터 값을 그대로 이벤트로 전달한다. 한 개의 값만 이벤트로 방출할 수 있다.

let element = "😀"

Observable.just(element)
    .subscribe{ event in print(event) } // next(😀)
    .disposed(by: disposeBag)

Observable.just([1,2,3])
    .subscribe{ event in print(event) } // next([1,2,3])
    .disposed(by: disposeBag)

of는 옵저버블 생성시 여러개의 값을 이벤트로 방출할 수 있다. of 메서드는 가변 파라미터로 선언되어있다.

Observable.of(1,2,3)
    .subscribe{ event in print(event) } // next(1), next(2), next(3)
    .disposed(by: disposeBag)

Observable.of([1,2], [3])
    .subscribe{ event in print(event) } // next([1,2]), next([3])
    .disposed(by: disposeBag)

from 연산자는 옵저버블 생성시 파라미터로 순회 가능한 데이터를 받아 순서대로 이벤트로 방출한다.

Observable.from([1,2,3])
    .subscribe{ element in print(element) } // next(1), next(2), next(3)
    .disposed(by: disposeBag)

# range, generate

range는 정수를 시작지점부터 count에 해당하는 값만큼 1씩 증카시켜 이벤트로 방출한다.

Observable.range(start: 1, count: 10)
    .subscribe{ print($0) } // next(1), next(2) ... next(10)
    .disposed(by: disposeBag)

generate는 시작지점부터 값의 변화 양상을 정의하고, 함께 정의된 조건이 true인 값들만 이벤트로 방출한다.

아래는 2이상 10 이하의 짝수의 값들만 출력해주는 옵저버블이다. condition 파라미터가 false가 되면 onCompleted가 호출되며 종료된다.

Observable.generate(initialState: 2, condition: { $0 <= 10 }, iterate: { $0 + 2 })
    .subscribe{ print($0) }
    .disposed(by: disposeBag)

# repeatElement

동일요소를 반복적으로 방출할때 사용하는 연산자이다.

Observable.repeatElement(element)
    .take(7)
    .subscribe{ print($0) }
    .disposed(by: disposeBag)

repeatElement는 반드시 take연산자와 함께 사용!

repeatElement는 take연산자를 사용하지 않으면 무한하게 요소를 방출한다. take연산자를 통해 몇개까지 방출할지 반드시 결정해줘야 한다.

# deferred

deferred는 특정 조건에 따라 옵저버블을 생성한다.

let animals = ["🐶", "🐱", "🐹", "🐰", "🦊", "🐻", "🐯"]
let fruits = ["🍎", "🍐", "🍋", "🍇", "🍈", "🍓", "🍑"]
var flag = true

let factory: Observable<String> = Observable.deferred {
    flag.toggle()

    if(flag){
        return Observable.from(animals)
    } else {
        return Observable.from(fruits)
    }
}

// flag - false - fruits가 방출
factory
    .subscribe{ print("factory >> ", $0)}
    .disposed(by: disposeBag)

// flag - true - animals가 방출
factory
    .subscribe{ print("factory >> ", $0)}
    .disposed(by: disposeBag)

deferred는 옵저버블을 리턴하는 클로저를 메서드 파라미터로 받는다. 위의 코드에서는 deferred호출에 따라 toggle되므로 리턴되는 옵저버블의 값이 달라지게 된다.

# create

create연산자는 옵저버블의 동작을 완전히 커스텀하고싶을때 사용한다. 위에서의 옵저버블들은 정수의 증가, 특정 요소의 선택 등 고정되어 있는 형태로 연산이 진행되었지만 create는 처음부터 끝까지 직접 동작에 대한 정의가 가능하다.

let observable = Observable<String>.create{ (observer) -> Disposable in
    guard let url = URL(string: "https://www.apple.com") else {
        observer.onError(MyError.error)
        return Disposables.create()
    }

    guard let html = try? String(contentsOf: url, encoding: .utf8) else {
        observer.onError(MyError.error)
        return Disposables.create()
    }

    observer.onNext(html)
    observer.onCompleted()
    return Disposables.create()
}

observable.subscribe{ print($0) }
    .disposed(by: disposeBag)

create 연산자 클로저를 구현할때는 반드시 onComplete 이후에 이벤트 방출이 이루어지지 않도록 해야한다. onError도 마찬가지이다.

create 연산자의 클로저 파라미터는 함수타입이다. 파라미터로 AnyObserver가 들어오며, Disposable을 리턴한다.

return Disposables.create()

클로저 파라미터의 리턴형이 Disposable이라고 하여 return Disposable.create()를 하면 안된다. 반드시 s를 붙여 Disposables.create()를 리턴해줘야 한다.

# empty, error

empty는 어떠한 것도 방출하지 않는 옵저버블을 정의할때 사용한다. 요소를 방출하지 않기 때문에 타입은 Void로 지정한다.

Observable<Void>.empty()
    .subscribe{ print($0) } // completed
    .disposed(by: disposeBag)

error 역시 어떤 요소도 방출하지 않으며, 에러를 리턴하는 옵저버블을 정의할때 사용한다.

Observable<Void>.error(MyError.error)
    .subscribe{ print($0) }
    .disposed(by: disposeBag)