본문 바로가기

iOS

[iOS] [Swift] RxSwift Operators Example

Operators Example

 

Create Operators


Just


image

 

just 연산자는 하나의 이벤트를 방출하는 Observable을 생성하는데 이용합니다.

 

let disposeBag = DisposeBag()

Observable.just("Hello")
    .subscribe(onNext: {  print($0) })
    .disposed(by: disposeBag)

Observable.just([1, 2, 3, 4, 5], scheduler: MainScheduler.instance)
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

/*
    Hello
    [1, 2, 3, 4, 5]
*/

 

위 예시와 같이 just는 단 하나의 이벤트를 생성하여 방출하고자 할 때 사용합니다.

 

just 연산자는 두 개의 종류가 제공되며 하나는 방출할 이벤트만 전달하여 생성하고 다른 하나는 방출할 이벤트와 어느 스케줄러로 전송할 지에 대한 스케줄러를 함께 전달하여 생성합니다.

 

파라미터로 배열을 전달하여도 해당 배열을 통째로 방출하는 것을 확인할 수 있습니다.

 

Of


image

 

앞서 살펴봤던 연산자 just 가 단 하나의 요소를 방출하기 위한 Observable을 생성하는 연산자라면 of는 가변할 수 있는 개수 만큼의 요소를 방출하기 위한 Observable을 생성하기 위한 연산자입니다.

 

즉, 방출하고자 하는 이벤트의 개수가 1 ~ N 개인 경우 사용이 가능한 연산자입니다.

 

let disposeBag = DisposeBag()

let yeo = "Yeo"
let jung = "Jung"
let su = "su"

Observable.of(yeo, jung, su)
    .subscribe(onNext: { print($0, terminator: " ") })
    .disposed(by: disposeBag)

/*
    Yeo Jung Su
*/

 

From

image

 

원형을 살펴보면 함수의 파라미터로 배열을 전달받고 반환형은 배열 요소 타입입니다.

 

from 연산자는 배열 형태의 element를 전달받아 내부 요소를 순차적으로 방출하는 Observable을 생성합니다.

 

let disposeBag = DisposeBag()

let arr = ["yeo", "jung", "su"]

Observable.from(arr)
    .map { $0 + "😄" }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

/*
    yeo😄
    jung😄
    su😄
*/  

 

출력 결과를 보면 앞서 얘기했던 것 처럼 배열 내 요소가 순차적으로 방출되어진 것을 볼 수 있습니다.

 

Filtering Operators


앞서 Observable 생성에 사용되는 주요 연산자들에 대하여 살펴봤습니다.

 

이번에는 필터링을 위한 연산자들을 살펴보도록 하겠습니다.

 

filter

image

 

필터링 연산자 중 자주 쓰이는 filter 입니다.

 

요소들을 필터링 하기 위한 기준 predicate 를 클로저로 받아서 해당 결과를 true 값을 반환하는 이벤트를 방출합니다.

 

let disposeBag = DisposeBag()

let numArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Observable.from(numArr)
    .filter { $0 % 2 == 0 }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

/*
    2
    4
    6
    8
    10
*/

 

 

filter 파라미터로 전달된 클로저를 살펴보면 element % 2 == 0 즉, 짝수 값만 true를 반환하는 클로저를 전달하였습니다.

 

따라서, 짝수 element만 출력되어집니다.

 

take


image

 

take 연산자는 정수값을 파라미터로 전달받습니다.

 

그리고 해당 숫자만큼의 요소만 방출하게 됩니다.

 

let disposeBag = DisposeBag()

let numArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Observable.from(numArr)
    .take(3)
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

/*
    1
    2
    3
*/

 

1~10까지의 숫자로 구성된 배열 내 요소를 순차적으로 방출하는 Observable을 생성하고 take 연산자의 파라미터로 3을 전달하였습니다.

그 결과 앞에서부터 3개의 정수만 순차적으로 출력되어진 것을 확인할 수 있습니다.

 

distinctUntilChanged


image

 

다음으로 distinctUntilChanged 연산자입니다.

 

이름을 보면 느낌이 오듯 요소에 대한 변화가 있을때만 방출하는 연산자입니다.

 

직접 예시로 살펴보도록 하겠습니다.

 

let disposeBag = DisposeBag()

let arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]

Observable.from(arr)
    .distinctUntilChanged()
    .subscribe(onNext: { print ($0) })
    .disposed(by: disposeBag)

/*
    1
    2
    3
    4
    5
*/

 

arr 배열은 1~5까지 각각의 원소가 순차적으로 두 번씩 반복되는 형태로 제작되었습니다.

 

해당 배열의 요소들을 순차적으로 방출하는 Observable을 생성한 이후, distinctUntilChanged 함수를 이용하여 필터링을 진행한 결과 방출하고자 하는 요소가 이전 요소와 다른 경우에만 방출되는 것을 확인할 수 있습니다.

 

Transforming


map


 

RxSwift의 map의 기능은 Swift에서 사용되는 고차함수 map 과 동일한 기능을 합니다.

 

다른점이 있다면 Observable을 리턴한다는 것 입니다.

 

let disposeBag = DisposeBag()

let languageNameArr = ["Swift", "Objective-c", "Kotlin" ,"Go"]

Observable.from(languageNameArr)
    .map { "Hello, \($0)" }
    .subscribe(onNext: { print($0)})
    .disposed(by: disposeBag

/*
    Hello, Swift
    Hello, Objective-c
    Hello, Kotlin
    Hello, Go
*/

 

Combining


 

concat


image

 

concat 타입메서드는 sequence 타입, collection 타입 등을 파라미터로 전달받아 해당 컬렉션 내부에 있는 요소들을 순차적으로 연결하여 하나의 Observable로 반환합니다.

 

let disposeBag = DisposeBag()
let oneToFive = Observable.from([1, 2, 3, 4, 5])
let sixToTen = Observable.from([6, 7, 8, 9, 10])

Observable.concat([oneToFive, sixToTen])
    .subscribe(onNext: { print ($0)} )
    .disposed(by: disposeBag)

/*
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
*/

 

CombineLatest


image

 

combineLatest 연산자는 여러 형태의 메소드를 제공하지만 가장 기본적으로 사용되는 형태는 위와 같습니다.

 

두 개의 Observable O1, O2를 전달받고 resultSelector라는 클로저를 전달받습니다.

 

해당 클로저 내부에는 O1, O2의 element가 전달되고, 클로저의 실행 결과는 element 하나의 요소를 리턴합니다.

 

이어서 최종적으로 클로저가 리터너한 하나의 요소를 방출하는 Observable을 반환합니다.

 

combineLatest는 최대 8개 까지 Observable을 전달받을 수 있도록 선언되어 있으며 파라미터의 개수만 다를뿐 동작은 동일합니다.

 

let disposeBag = DisposeBag()

let platforms = PublishSubject<String>()
let languages = PublishSubject<String>()

Observable.combineLatest(platforms, languages) { " Hi \($0 + " " + $1)"}
    .subscribe(onNext: { print ($0) })
    .disposed(by: disposeBag)

platforms.onNext("iOS")
languages.onNext("Swift")

platforms.onNext("AOS")
languages.onNext("Kotlin")

/*
    Hi iOS Swift
    Hi AOS Swift
    Hi AOS Kotlin
*/

 

두 개의 Observable에서 최근에 방출된, Latest한 요소값들 끼리의 조합 결과를 반환하기에 위와 같은 결과를 볼 수 있습니다.

 

zip


image

 

zip 연산자는 source Observable이 방출하는 요소들을 결합합니다.

 

앞서 살펴봤던 combineLatest 연산자는 가장 최근 요소들을 기준으로 클로저를 실행하지만 zip은 클로저에게 중복되는 요소를 전달하지 않습니다.

 

index 기준으로 짝을 맞춰 요소를 전달하여 작동하게 됩니다.

 

let disposeBag = DisposeBag()

let numbers = PublishSubject<Int>()
let strings = PublishSubject<String>()

Observable.zip(numbers, strings) { "\($0)" + " " + "\($1)" }
    .subscribe(onNext: { print ($0) })
    .disposed(by: disposeBag)

numbers.onNext(1)
strings.onNext("One")

numbers.onNext(2)
strings.onNext("Two")

numbers.onNext(3)
strings.onNext("Three")

/*
    1 One
    2 Two
    3 Three
*/

 

Summary


Create

  • just: 단 하나의 이벤트를 방출하는 Observable 생성

  • of: 하나 혹은 여러 개의 이벤트를 방출하는 Observable 생성

  • from: 배열 형태의 element를 전달받아 내부 요소를 하나하나 방출하는 Observable을 생성

 

Filter

  • filter: 함수 파라미터로 predicate 역할의 클로저를 전달받으며 해당 결과가 true 값인 요소만 방출됩니다.

  • take: 함수 파라미터로 정수값을 전달받으며 해당 숫자만큼의 이벤트를 방출합니다.

  • distinctUntilChanged: 이전에 방출한 요소값과 현재의 요소가 다른 경우에만 요소를 방출합니다.

 

Transforming

  • map: Swift의 고차함수 map과 동일한 기능을 하며 Observable을 반환합니다.

 

Combining

  • concat: 이름 그대로 컬렉션 타입의 파라미터들을 순차적으로 연결하여 하나의 Observable을 반환합니다.

  • combineLatest: 하나 이상의 Observable을 파라미터로 전달받으며 해당 Observable의 요소들 중 최근값들을 조합한 값을 반환하는 Observable을 반환합니다.

  • zip: 1~3개 의 source Observable을 파라미터로 전달받으며 해당 Observable의 요소들을 index 순에 맞춰서 조합한 값을 반환하는 Observable을 반환합니다.

'iOS' 카테고리의 다른 글

[iOS] [Swift] UIKit Framework  (0) 2020.12.04
[iOS] [Swift] RxCocoa 맛보기  (0) 2020.11.26
[iOS] [Swift] RxSwift Subject & Relay & Driver  (1) 2020.11.19
[iOS] [Swift] RxSwift Observable & Observer, Disposable  (0) 2020.11.19
[iOS] Blur Effect in iOS  (0) 2020.11.11