아요 개발 일기

[RxSwift] Observable 연산자 [just, of, from, range, empty, never] (1) 본문

iOS/RxSwift

[RxSwift] Observable 연산자 [just, of, from, range, empty, never] (1)

소진이 2023. 1. 3. 15:40

안녕하세요 소진입니다 :)

이번 글에서는 Observable 연산자에대해 알아보도록 하겠습니다!

Observable에대해 모른다면 [RxSwift] Observable과 subscribe 글을 참고해주세요ㅎㅎ


Observable 생성 연산자

우선 Observable을 생성하는 연산자는

묶어서 알아보도록하겠습니다!

 

✔️ just

✔️ of

✔️ from

 

대표적인 생성 연산자는 위와 같습니다.

차근차근 하나씩 알아봅시다 :)

 

좀 더 섬세한 컨드롤이 필요하다면 create를 이용하여 생성할 수 있음

 


 

  just  

 

just는 아래 마블 이미지로도 확인 가능하듯이 오직 하나의 요소를 방출시키고

끝나는 ObservableType 프로토콜의 TypeMethod 입니다.

 

 

사용방법

 

just는 단 하나의 요소만 방출시키기 때문에

.just() 호출과 동시에 방출 시킬 값을 넣어주면 됩니다.

간단하죠?

 

 

// 요소 방출
let justObservable = Observable.just("hello world")

// 이벤트 처리
justStringObservable.subscribe (onNext: { element in
    print(element)
}, onCompleted: {
    print("completed")
})

[실행 결과]
// hello world
// completed

 

타입 제한

 

아래 코드처럼 작성하면 

just에 넣는 값을 제한시켜줄 수 있습니다.

 

타입 제한을 준 상태에서 just() 안에 다른 타입의 값을 넣어주면 에러가 발생하니 주의!

 

let justStringObervable: Observable<String> = Observable.just("Hello World")

 


 

  of  

 

위에서 just가 단 하나의 요소만 방출했었죠?

of는 여러개의 요소들을 순차적으로 방출하는 연산자 입니다

 

 

사용방법

 

여러개의 요소를 방출하는 연산자이므로

,로 데이터를 여러개 넣어주면 됩니다!

 

// 요소 방출
let ofObservable = Observable.of("hi", "my", "name", "is", "sojin")

// 이벤트 처리
ofObservable.subscribe { element in
    print(element)
} onCompleted: {
    print("completed")
}

[실행 결과]
// hi
// my
// name
// is
// sojin

 

⚠️ 주의 사항 ⚠️

 

 of() 안에 들어가는 요소들은 타입 추론이 되어서 타입 제한이 생기기 때문에

하나의 타입으로 통일 시켜줘야 합니다.

 

// Error
let ofObservable = Observable.of("hi", "i'm", 3, "years", "old", "sojin")

// Ok
let ofObservable: Observable<Any> = Observable.of("hi", "i'm", 3, "years", "old", "sojin")

하지만, 두번째 코드처럼 타입을 Any로 준다면 다양한 타입도 가능하겠죠?

 

 


 

  from  

 

배열로 요소를 받은 후에 하나하나 요소로서 방출해주는 연산자

 

// 요소 방출
let fromObservable = Observable.from(["Apple", "is", "Red"])

// 이벤트 처리 
fromObservable.subscribe{ element in
    print(element)
} onCompleted: {
    print("completed")
}

[실행 결과]
// Apple
// is
// green
// completed

 

어.. 그런데

of 연산자랑 비슷한 것 같죠??

 

 

["Apple", "is", "Red"]

 

위 배열을 그대로 넣어보고

어떻게 다른지 살펴 봅시다!

 

.of()

// 요소 방출
let ofObservable = Observable.of(["Apple", "is", "Red"])

// 이벤트 처리
ofObservable.subscribe { element in
    print(element)
} onCompleted: {
    print("completed")
}

[실행 결과]
// ["Apple", "is", "Red"]
// completed

 

.from()

// 요소 방출
let fromObservable = Observable.from(["Apple", "is", "Red"])

// 이벤트 처리
fromObservable.subscribe { element in
    print(element)
} onCompleted: {
    print("completed")
}

[실행 결과]
// Apple
// is
// Red

of는 배열 그대로 전달하고

from은 배열의 값 하나하나를 전달하네요!

 


range

 

for문과 같이 Observable에서도 요소를 단순히 연속적으로 반복 방출 시킬 수 있도록

도와주는 연산자

 

사용방법

 

range는 Int타입으로 타입 제한이 걸려있으므로

타입 제한을 줄 필요는 없습니다.

 

아래 코드처럼 range는 start와 count 파라미터를 가지고 있습니다.

말 그대로 각 파라미터는 start 값부터 count 값 번 반복 할 것인지 정해주는 역할을 합니다.

 

 start..<count 

 

// 요소 출력
let rangeObservable = Observable.range(start: 0, count: 10)

// 이벤트 처리
rangeObservable.subscribe(onNext: { element in
    print(element)
})

[실행 결과]
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

 

위 코드에서 start 값이 0 count 값이 10이니

0..<10 이겠죠?

그래서

0~9까지 반복한 값을 출력된 것을 알 수 있습니다.

 

우리가 위에서 작성한 range 코드를

from을 이용해 똑같이 나타낼 수도 있는데,

 

 from(0..<10) 

 

이렇게 표현하면됩니다!

// 요소 방출
let fromObservable = Observable.from(0..<10)

// 이벤트 처리
rangeObservable.subscribe(onNext: { element in
    print(element)
})

[실행 결과]
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

 

하지만, 

명확한 의미 전달을 위해서 range를 사용하는게 좋겠죠?

 


 

empty

 

이 연산자는 이름부터 뭔가 값을 비워주는 역할을 할 것 같죠?ㅎㅎ

맞습니다!

바로 초기화 해주는 연산자입니다.

 

// Error (일반적인 방식)
let emptyObservable: Observable = Observable<Any>()

// Succeed
let emptyObservable: Observable = Observable<Any>.empty()

 

위 코드처럼 empty()를 일반적인 방식으로 초기화 하려고하면

에러가 발생기때문에

 

Succeed에 있는 코드처럼 작성해야

오류 없는 빈 Observable을 선언 할 수 있습니다.

 

 

이렇게 empty()는 Observabel을 초기화 할때도 사용하지만,

즉시 completed되는 Observable이나

element가 0개인 Observable을 의도적으로 리턴하고 싶을 때에도

유용하게 사용될 수 있습니다!

 


 

never

 

Observable이 아무런 이벤트도 방출시키지 않도록 해주는 연산자

단, onDisposed 제외

 

사용 방법

 

구현하는 법은 empty()와 유사합니다.

let neverObservable = Observable<Int>.never()

 

 

휴..

observabel 연산자는

글 하나에 다 작성할 수 있을 줄 알았는데..

글이 너무 길어져서 Disposable, create, deferred는

다음 포스팅에서 다루도록 하겠습니다!

 


 

마치며..

 

just

: 간단하게 하나의 요소만 방출

 

of

: 여러 요소들을 순차적으로 방출 (배열 그대로 방출)

 

from

: 배열의 값 하나하나를 방출

 

range

: 단순 방복 요소를 방출 (for문과 유사)

from으로도 동일하게 표현가능함 (But, 명확한 의미 전달을 위해 range 사용 권장)

 

empty

: 초기화

의도적으로 즉시 completed되는 Observable을 리턴하고 싶을 때에도 사용

 

never

: onDisposed를 제와하고 아무런 이벤트를 방출시키지 않음