์ƒˆ์†Œ์‹

๐Ÿ“ฑ iOS/-- RXSwift

RxSwift (1) ์ฃผ์š” ๊ฐœ๋… (Observable , Subscribe, Disposable, Operator)

  • -

Observable

ํ˜น์€ Observable Sequence , Sequence์™€๋„ ๊ฐ™์€ ๋ง์ด๋‹ค. ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด์ด๋ฉฐ, ๊ตฌ๋…์ž๊ฐ€ ์ด๋ฅผ ๊ตฌ๋…ํ•˜์—ฌ “์ด๋ฒคํŠธ”๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฒคํŠธ์—๋Š” 3๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

์ด๋ฒคํŠธ์˜ ์ „๋‹ฌ ๋ฐฉํ–ฅ : Observable -> Observer
์ด๋ฒคํŠธ์˜ ๊ด€์ฐฐ ๋ฐฉํ–ฅ : Observable <- Observer

์ด๋ฒคํŠธ์˜ ์ข…๋ฅ˜

Observable์€ 3๊ฐ€์ง€ ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š”๋ฐ, ๊ตฌ๋…์ž๋Š” ์ด๋ฅผ ๋ฐ›์•„ ํ•ด์•ผํ•  ์ผ๋“ค์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

  • Next: Emission์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ, ์›์†Œ(๊ฐ’)๋“ค์„ ๋ฐฉ์ถœํ•œ๋‹ค.
  • Completed: Observable์ด “์—๋Ÿฌ ๋ฐœ์ƒ ์—†์ด ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋ ๋•Œ” ์ „๋‹ฌ๋œ๋‹ค. Observable์˜ ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋๋‚œ๋‹ค.
  • Error: Observable์ด “์—๋Ÿฌ๋กœ ์ธํ•ด ์ข…๋ฃŒ๋ ๋•Œ” ์ „๋‹ฌ๋œ๋‹ค. Observable์˜ ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋๋‚œ๋‹ค.

Marble Diagram

https://rxmarbles.com

Observable์˜ ์ƒ์„ฑ์˜ˆ์‹œ

1. Create ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•œ ์ƒ์„ฑ

let observerble = Observable<Int>.create { (observer) -> Disposable in
    observer(50)
    observer(.next(100))
    observer()

    return Disposables.create()
}

2. From ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•œ ์ƒ์„ฑ

let observerble2 = Observable<Int>.from([-50, -100])

SubScribe

Observable์€ Observer์—๊ฒŒ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ์ด ์ „๋‹ฌ๋˜๋Š” ์‹œ์ ์€ observer๊ฐ€ observable์„ subscribeํ•˜๋Š” ์ˆœ๊ฐ„์ด๋‹ค. ์ฆ‰, ๊ด€์ฐฐ(๊ตฌ๋…)์„ ํ•˜์ง€ ์•Š์œผ๋ฉด ์ด๋ฒคํŠธ๋„ ์ „๋‹ฌ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋ง๊ณผ ๊ฐ™๋‹ค.

let ob1 = Observable<Int>.create { (observer) -> Disposable in
   observer.on(.next(0)) // ๊ตฌ๋…์ž์—๊ฒŒ 0์ด๋ผ๋Š” ๊ฐ’์„ ์ „๋‹ฌํ•œ๋‹ค.
   observer.onNext(1)  // ๊ตฌ๋…์ž์—๊ฒŒ 1์ด๋ผ๋Š” ๊ฐ’์„ ์ „๋‹ฌํ•œ๋‹ค.
   observer.onCompleted() // Observable์ด ์ •์ƒ ์ข…๋ฃŒ๋˜๋ฉฐ, ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋๋‚œ๋‹ค.
   return Disposables.create()
}


ob1.subscribe { event in
   print(event.element) // ์ด๋ ‡๊ฒŒ๋„ ๊ฐ’์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
    switch event{
    case .next(let element):
        print("element ->",element)
    case .completed:
        print("Completed!")
    case .error(let error):
        print(error)
    }
}

๊ตฌ๋…์„ ํ•˜๊ฒŒ๋˜๋ฉด Event๋ฅผ ์ „๋‹ฌ๋ฐ›๊ฒŒ๋˜๊ณ , ์œ„์—์„œ ๋งํ–ˆ๋“ฏ์ด 3๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— switch๋กœ ๋ถ„๊ธฐํ•  ์ˆ˜ ์žˆ๋‹ค.
Switch๋ฌธ ๋ฐ–์—์„œ onNext๋กœ ์ „๋‹ฌ๋ฐ›์€ ๊ฐ’์— ์ง์ ‘ ์ ‘๊ทผํ•˜๋ ค๋ฉด event.element ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  Subscribe(๊ด€์ฐฐ)์„ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›๋Š” ์ด๋ฒคํŠธ๋Š” ํ•œ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ๋งŒ ์ „๋‹ฌ๋ฐ›๊ฒŒ๋œ๋‹ค.

Disposable

Observable๊ณผ ๊ด€๋ จ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ •๋ฆฌํ•˜๋Š” ์ฝ”๋“œ

var bag = DisposeBag()

let ob = Observable.from([1,2,3])
    .subscribe { element in
        print("onNext: \(element)")
    } onError: { error in
        print("Error: \(error)")
    } onCompleted: {
        print("onCompleted")
    } onDisposed: {
        print("Disposed")
    }.disposed(by: bag)

bag = DisposeBag() 

์—ฌ๊ธฐ์„œ Disposed๋Š” Observable์ด ์ „๋‹ฌํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์•„๋‹ˆ๋‹ค. Observable๊ณผ ๊ด€๋ จ๋œ ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์— Disposed ํด๋กœ์ €๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

Disposable ์šฉ๋„

  • Observable๊ณผ ๊ด€๋ จ๋œ ๋ฆฌ์†Œ์Šค๋“ค์„ ์ •๋ฆฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
  • ์‹คํ–‰ ์ทจ์†Œ์— ์‚ฌ์šฉ๋œ๋‹ค.

๋งŒ๋“ค์–ด๋†จ๋˜ DisposeBag ํ”„๋กœํผํ‹ฐ์— ์ƒˆ๋กœ์šด DisposeBag๋ฅผ ๋„ฃ์œผ๋ฉด bag์•ˆ์— ์žˆ๋˜ Disposable๋“ค์ด ํ•ด์ œ๋œ๋‹ค.
๋˜๋Š” ์˜ต์…”๋„๋กœ ํ•ด์„œ nil์„ ๋„ฃ์–ด์ค˜๋„ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

Disposable์„ ์‹คํ–‰์ทจ์†Œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

// ์‹คํ–‰ ์ทจ์†Œ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ
let ob2 = Observable<Int>
    .interval(.seconds(1), scheduler: MainScheduler.instance)
    .subscribe { element in
        print("onNext: \(element)")
        if element == 3{
            bag = DisposeBag()
        }
    } onError: { error in
        print("Error: \(error)")
    } onCompleted: {
        print("onCompleted")
    } onDisposed: {
        print("Disposed interval")
    }.disposed(by: bag)

Operators (์—ฐ์‚ฐ์ž)

Observable์„ ์ƒ์„ฑ, ๋ฐฉ์ถœ, ํ•„ํ„ฐ๋ง ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋“ค์ด ์žˆ๋Š”๋ฐ ์ด๊ฒƒ๋“ค์„ ํ†ตํ‹€์–ด Operators๋ผ๊ณ  ํ•œ๋‹ค.
Map, filter, take….. ๋“ฑ ๊ฝค ์—ฌ๋Ÿฌ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค. ๋งˆ๋ธ” ๋‹ค์ด์–ด๊ทธ๋žจ์„ ํ†ตํ•ด์„œ ์‹œ๊ฐ์ ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
RxMarbles: Interactive diagrams of Rx Observables

Take operator

Observable.from([1, 2, 3, 4, 5, 6, 7, 8, 9])
    .take(5)
    .subscribe { print($0) }
    .disposed(by: bag)

Take operator๋Š” emit์„ 5ํšŒ ์‹คํ–‰ํ•œ๋‹ค.

 

'๐Ÿ“ฑ iOS > -- RXSwift' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

(RxSwift) Error ๋‹ค๋ฃจ๊ธฐ, Retry, Catch  (0) 2023.05.26
RxSwift (2) - Subject & Relay  (0) 2023.05.17
Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.