๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS

[RxSwift] Observable, Operators ๊ทธ๋ฆฌ๊ณ  subscribe

by ํ‹ด๋”” 2022. 1. 5.
728x90
๋ฐ˜์‘ํ˜•

- ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ”Œ๋กœ์šฐ ์•„ํ‚คํ…์ฒ˜์— ์ ์šฉ์‹œํ‚ค๊ธฐ ์œ ๋ฆฌํ•จ

- ๋ฐ˜์‘ํ˜•์•ฑ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค ํ•„์š”๋Š” ์—†์Œ(์ผ๋ถ€์˜ ์ฝ”๋“œ๋“ค์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ , ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ RxSwift๋กœ ์ •์˜ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค)

- MVVM + RxSwift ์กฐํ•ฉ

ใ„ด ViewModel Observable<T> ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐฉ์ถœํ•˜๊ฒŒ ํ•˜๋Š”๋ฐ ์ด๋Š” View controller์˜ ๊ณ ์ •๋œ ์ฝ”๋“œ์—์„œ UIKit controls๊ฐ€ ์ง์ ‘์ ์œผ๋กœ ๋ฐ”์ธ๋“œ ๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Œ -> Observable<T> ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ UIKit์˜ Controls ์š”์†Œ๋ฅผ ์˜ต์ €๋น™ ํ•  ์ˆ˜ ์žˆ์Œ

 

Podfile์—์„œ 2022๋…„ 1์›” ๊ธฐ์ค€ ์•„๋ž˜ pod ์ถ”๊ฐ€

    pod 'RxSwift', '6.1.0'
    pod 'RxCocoa', '6.1.0'

pod install ๋กœ ์„ค์น˜ ์™„๋ฃŒ ํ›„ ํ”„๋กœ์ ํŠธ ์žฌ ์‹คํ–‰.

mvvm๊ณผ swift์˜ ์กฐํ•ฉ์ด ์ข‹๋‹ค๊ณ  ํ•˜๋Š”๋ฐ ์•„์ง ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹น. ํด๋” ๋ถ„๋ฆฌ!

xib์—์„œ ์Šค์œ„์น˜๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜์—ฌ constraint ์ฃผ๊ณ  swift ํŒŒ์ผ๊ณผ IBOutlet ์—ฐ๊ฒฐ

@IBOutlet weak var rxSwitch: UISwitch!

swift ํŒŒ์ผ์—์„œ RxSwift์™€ RxCocoa๋ฅผ import ํ•ด์ค€๋‹ค ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ RxCocoa๋ฅผ ํ•ด์ฃผ์–ด์•ผ Rx์—์„œ ์›ฌ๋งŒํ•œ uikit ๊ตฌํ˜„ํ•ด ๋†“์€ ๊ธฐ๋Šฅ์„ ์“ธ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์žŠ์ง€ ๋ง๊ณ  import ํ•ด์ค€๋‹น RxSwift ๋งŒ ํ•ด์ฃผ๊ณ  ๋ฒ„์ „ ๋ฌธ์ œ๋กœ ์•ˆ๋˜๋Š” ์ค„ ์•Œ๊ณ  ์–ด์ฉŒ์ง€ ํ–ˆ๋Š”๋ฐ ์ž„ํฌํŠธ๋งŒ ์ž˜ ํ•ด์ฃผ๋ฉด ๋˜๋Š”๊ฑฐ์˜€๋‹น

import UIKit
import RxSwift
import RxCocoa

class SwitchTestViewController: UIViewController {

    @IBOutlet weak var rxSwitch: UISwitch!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        rxSwitch.rx.isOn
            .subscribe { isOn in
                print(isOn ? "์Šค์œ„์น˜ ์ผœ์ง" : "์Šค์œ„์น˜ ๊บผ์ง")
            }
        
    }
}

import UIKit ์ œ๊ฑฐํ•ด์ค˜๋„ ๋จ.

์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด control์„ ์˜ต์ €๋น™ ํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ

UITextField, URLSession, UIViewController์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ. rx ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ ๋ฆฌ์•กํ‹ฐ๋ธŒ ์ต์Šคํ…์…˜ ์‚ฌ์šฉ์ž ์ •์˜๊ฐ€ ๊ฐ€๋Šฅํ•จ

 

Observables

- observable == observable sequence == sequence 

ํŠนํžˆ RxSwift์—์„œ๋Š” stream์ด๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์•„๋‹Œ sequence๋กœ ์‚ฌ์šฉ

- observable์ด์•ผ ๋ง๋กœ ์‹œํ€€์Šค! ๋น„๋™๊ธฐ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—„์ฒญ๋‚œ ํž˜์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ํ•จ 

- Observables๋Š” ์ผ์ • ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ฐฉ์ถœ์ด๋ผ๊ณ  ํ•˜๋Š” event๋ฅผ ๋ฐœ์ƒ์‹œํ‚ด

- ์ด๋ฒคํŠธ๋Š” ๊ฐ’์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ˆซ์ž๋‚˜ ์ปค์Šคํ…€ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋„ ํฌํ•จ๋˜๋ฉฐ ํƒญ์„ ๋ˆŒ๋Ÿฌ ์ œ์Šค์ฒ˜๋ฅผ ์ธ์‹ํ•˜๋Š” ๊ฒƒ๋„ ์ด ์ด๋ฒคํŠธ์— ํฌํ•จ๋œ๋‹ค ์œ„์—์„œ ์Šค์œ„์น˜๊ฐ€ ๊ทธ๋ž˜์„œ ๊ฐ€๋Šฅํ•œ ๊ฒƒ

 

RxSwift์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋งˆ๋ธ” ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์•„๋ž˜ ์‚ฌ์ดํŠธ์—์„œ ์‰ฝ๊ฒŒ ํ™•์ธ ๊ฐ€๋Šฅํ•จ

https://rxmarbles.com/

 

RxMarbles: Interactive diagrams of Rx Observables

 

rxmarbles.com

-> ํ™”์‚ดํ‘œ๋Š” ์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๊ณ  ์ˆซ์ž๊ฐ€ ์ ํ˜€ ์žˆ๋Š” ๋™๊ทธ๋ผ๋ฏธ๋Š” sequence๋ฅผ ๋‚˜ํƒ€๋ƒ„ ์—ฌ๊ธฐ์„œ ์‹œํ€€์Šค๋ž€ ์•ž์—์„œ ๋งํ•œ observable๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด๋ฉด ๋จ

 

์—ฌ๊ธฐ์„œ 1์ด ๋ฐฉ์ถœ๋˜๊ณ  ์‹œ๊ฐ„์ด ์กฐ๊ธˆ ํ๋ฅด๋ฉด 2๊ฐ€ ๋ฐฉ์ถœ๋˜๊ณ  ๊ทธ ๋‹ค์Œ 3, ๊ทธ ๋‹ค์Œ 4๊ฐ€ ๋ฐฉ์ถœ๋˜๋Š” ๊ฒƒ์„ ํƒ€์ž„ ๋ผ์ธ์œผ๋กœ ํ‘œ์‹œ ํ•ด ๋‘” ๊ฒƒ!

Observable์˜ ์ด๋ฒคํŠธ์—๋Š” ์„ธ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ

.next, .completed, .error ๊ฐ€ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ .completed ๋ฅผ ์‚ดํŽด๋ณด์ž๋ฉด

ํ™”์‚ดํ‘œ ๋งˆ์ง€๋ง‰์— ์žˆ๋Š” ์„ธ๋กœ ๋ง‰๋Œ€๊ธฐ๋Š” observable์˜ ๋์„ ์˜๋ฏธํ•จ

์—ฌ๊ธฐ์„œ observable์€ 4๊ฐœ์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๊ณ  ๋๋‚จ ์ด๊ฒƒ์„ completed ์ด๋ฒคํŠธ๋ผ๊ณ  ํ•จ

์ด ํƒ€์ž„๋ผ์ธ์—์„œ ์‹œํ€€์Šค๋Š” ์ด๋ฏธ ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์ ธ ๋ณด์ด์ง€ ์•Š๋Š” dismiss ๋œ ๋ทฐ์—  ์กด์žฌํ•˜๊ณ  ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค! ์ด๋•Œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด๋ฒคํŠธ์ด๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ๋‚จ๊ฒจ๋‘˜ ํ•„์š”๊ฐ€ ์—†์–ด ์ฆ‰์‹œ ์ข…๋ฃŒ์‹œํ‚ค๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค. ๋˜ํ•œ ์ด observable์ด ๋” ์ด์ƒ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜์ง€๋„ ์•Š์œผ๋ฏ€๋กœ ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ์‹œํ‚ค๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค. ๋งŒ์•ฝ์— ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๊ฐ€ ์•ˆ๋˜์—ˆ์„ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด error ์ด๋‹ค

terminate ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ด๋ฒคํŠธ๋Š” ๋‘ ๊ฐ€์ง€ ์ธ๋ฐ ํ•˜๋‚˜๋Š” completion์ด๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” error ์ธ ์…ˆ์ด๋‹ค.

์—๋Ÿฌ ์ด๋ฒคํŠธ๋Š” ํ™”์‚ดํ‘œ ์„ ์ƒ์—์„œ x๋กœ ํ‘œ์‹œ๋œ๋‹ค

์—๋Ÿฌ์ด๋ฒคํŠธ๊ฐ€ ๋ฐฉ์ถœ๋˜๋ฉด ์ฆ‰์‹œ observable์€ ์ข…๋ฃŒ๋˜๊ณ  ๋” ์ด์ƒ ์•„๋ฌด๊ฒƒ๋„ ๋ฐฉ์ถœํ•  ์ˆ˜ ์—†๋‹ค

 

terminated์ด๋ฒคํŠธ๊ฐ€ ๋ฐฉ์ถœ๋˜๋ฉด ๋” ์ด์ƒ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•  ์ˆ˜ ์—†์Œ!

 

 

์–ด๋Š ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋Š”์ง€๋Š” Pods์˜ RxSwift ์—์„œ Event.swift <- ์ด ์•ˆ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

        rxSwitch.rx.isOn
            .subscribe { isOn in
                print(isOn)
            } onError: { error in
                print(error.localizedDescription)
            } onCompleted: {
                print("completed")
            } onDisposed: {
                print("disposed")
            }

error ํƒ€์ž…์ด Swift Error ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— localizedDescription๋กœ ์ฐ์–ด ๋ณผ ์ˆ˜ ์žˆ์Œ 

 

์ด์ œ Observable์„ ์ƒ์„ฑํ•˜๋Š” 'Operator'์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Œ!

Observable.XXX() ์™€ ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋ฅผ RxSwift์—์„œ๋Š” Operator๋ผ๊ณ  ํ•œ๋‹ค! ๋ญ๊ฐ€ ์žˆ๋Š”์ง€ ์‚ดํŽด ๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด cheat sheet๋„ ์žˆ๋‹น!

https://cheatography.com/donghua-li/cheat-sheets/rxswift-operators/

 

RxSwift Operators Cheat Sheet

RxSwift supported operators

cheatography.com

 

์šฐ์„  ํ•˜๋‚˜์˜ ์š”์†Œ๋ฅผ ๋‹ด์€ Observable sequence๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์˜คํผ๋ ˆ์ดํ„ฐ๋Š” just ์ด๋‹ค!

        let dog = 0
        let cat = 1
        let bird = 2
        
        let animalObservable = Observable<Int>.just(dog)

์ด๋ ‡๊ฒŒ ์ƒ์„ฑํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค. cheat sheet๋ฅผ ์‚ดํŽด๋ณด๋ฉด 'emit a particular item'์ด๋ผ๊ณ  ์ ํ˜€์žˆ๋Š”๋ฐ ํŠน์ •ํ•œ ์•„์ดํ…œ์„ ๋ฐฉ์ถœํ•˜๋Š” ์˜ต์ €๋ฒ„๋ธ”์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค!

 

๊ทธ ๋‹ค์Œ ์‚ดํŽด๋ณผ ๊ฒƒ์€ of ์ธ๋ฐ ์ด๊ฒƒ์€ just์™€ ๋‹ฌ๋ฆฌ ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ๋‹ด์€ Observable  ์‹œํ€€์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค

let animalsObservable = Observable.of(dog, cat, bird)

์š”๋กœ์ฝ”๋กฌ ์ƒ์„ฑํ•ด ์ฃผ๋ฉด ๋˜๊ฒ ๋‹ค! ๋งŒ์•ฝ์— of ์˜คํผ๋ ˆ์ดํ„ฐ์— ์ธ์ž๋กœ ๋“ค์–ด๊ฐ„ dog, cat, bird ๊ฐ’์ด Int ํƒ€์ž…์ด๋ฉด ์˜ต์ €๋ฒ„๋ธ”์˜ Element๋Š” int ํƒ€์ž…์ธ ๊ฒƒ! ๋งŒ์•ฝ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํ˜น์€ ์ „๋‹ฌ๋œ๋Š” ๊ฐ’์„ ์–ด๋ ˆ์ด๋กœ ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด 

let animalsObservable = Observable.of([dog, cat, bird])

์ด๋ ‡๊ฒŒ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค! ๊ทธ๋ ‡๋‹ค๋ฉด ๋‚ด๊ฐ€ ์–ด๋ ˆ์ด๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๊ณ  ์ด ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ์˜ต์ €๋ฒ„๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค! ํ•  ๋•Œ ํ•˜๋‚˜ํ•˜๋‚˜ ํ•ด์ค˜์•ผ ํ• ๊นŒ? ๋…ธ๋†‰ ์ด๋ฏธ from์ด๋ผ๋Š” ์˜คํผ๋ ˆ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค!

์œ„์—์„œ of๋กœ ์ƒ์„ฑํ•œ ์˜ต์ €๋ฒ„์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋ณด๋ฉด

int ์–ด๋ ˆ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค! ์ฆ‰ ์ƒ์„ฑํ•œ ๊ฒƒ์€ [Int] ํƒ€์ž…์˜ ์˜ต์ €๋ฒ„!

let animalsObservable = Observable.of([dog, cat, bird])
        
let animalObservables = Observable.from([dog, cat, bird])

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ from์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค? (์œ„์—๋Š” of, ๋ฐ‘์—๋Š” from)

๊ทธ๋Ÿฌ๋ฉด ๊ฒฐ๊ณผ ๊ฐ’์€

์ด๋Ÿฌํ•˜๋‹ค! Int ํƒ€์ž…์˜ ์˜ต์ €๋ฒ„๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์ž‡๋Š”๋ฐ enumerable ์‹œํ€€์Šค๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์–ด๋ ˆ์ด๋ฅผ ์˜ต์ €๋ฒ„๋กœ ์ƒ์„ฑํ•œ๋‹ค. from ์€ ๋ฌด์กฐ๊ฑด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์–ด๋ ˆ์ด ํƒ€์ž…์„ ๋ฐ›๋Š”๋‹ค!

์ •๋ฆฌ>>>

of ์—์„œ Element๊ฐ€ [Int] ์ด๋ฉด ๊ฒฐ๊ณผ๋Š” Observable<[Int]>

from ์—์„œ Element๊ฐ€ [Int] ์ด๋ฉด ๊ฒฐ๊ณผ๋Š”  Observable<Int>

์‚ฌ์‹ค ์ž˜ ์ดํ•ด ์•ˆ๋˜๋Š”๊ฒŒ ์–ด๋ ˆ์ด๋ฅผ ๋„ฃ์—ˆ๋Š”๋ฐ ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•œ๊ฐœ ๋‚˜์˜ค๋Š” ๊ฑด์ง€ ์‹ ๊ธฐํ•˜๋‹น ์ด๋Ÿฐ๊ฑด ๋‹ค๋ฅธ๊ฑฐ ๋ณด๋ฉด์„œ ์ตํžˆ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ์–ด! ํ•˜๋ฉด์„œ ์•Œ๊ฒŒ๋˜๋Š” ๊ฒƒ์ด ์ตœ๊ณ ์ž„

 

๊ทธ๋Ÿฐ๋ฐ ๋นŒ๋“œํ•ด๋ณด๋ฉด ์•„๋ฌด๊ฒƒ๋„ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค! why? ๋ฐ”๋กœ ๊ตฌ๋…์„ ์•ˆํ–ˆ๊ธฐ ๋•Œ๋ฌธ!

Observable์€ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ์˜ต์ €๋น™ ๊ฐ€๋Šฅํ•œ ์นœ๊ตฌ์ธ๋ฐ ์ด ์นœ๊ตฌ์˜ ๊ฐ’์„ ๋ฐ›์•„๋ณด๊ณ  ์‹ถ์œผ๋ฉด ๊ตฌ๋…ํ•ด์ค˜์•ผ ํ•จ! ์œ ํŠœ๋ธŒ๋ž‘ ๋น„์Šทํ•œ ๊ฑด๊ฐ€ ๋ณด๋‹ค. ์œ ํŠœ๋ฒ„๊ฐ€ Observable์ด๊ณ  ์—ฌ๊ธฐ ์ƒˆ ๋™์˜์ƒ์ด ์˜ฌ๋ผ์˜ค๋ฉด Element์ธ๊ฑฐ๊ณ  ์ด๊ฑฐ์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›๊ณ  ์‹ถ๋‹ค ๊ทธ๋Ÿฌ๋ฉด ๊ตฌ๋… ์ข‹์•„์š” ์•Œ๋ฆผ ์„ค์ • ํ•ด์ฃผ๋Š” ๊ฑด๊ฐ€๋ณด๋‹น  ์˜ˆ์‹œ๊ฐ€ ์ •ํ™•ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ...

 

Subscribing

์šฐ์„  ์ด์ „์— observable์—์„œ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•ด์•ผ ํ•  ๋ถ€๋ถ„์€ observable ์€ ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค! ๋ง๊ทธ๋Œ€๋กœ ์˜ต์ €๋ฒ„๋งŒ ์ƒ์„ฑํ•ด ๋†“์€ ์ƒํƒœ! ์ด์ œ ์—ฌ๊ธฐ์„œ ์ด ์˜ต์ €๋ฒ„๋ฅผ ๊ตฌ๋…ํ•˜๋Š” subscriber๊ฐ€ ์ƒ๊ฒจ์•ผ ์ด๋ฒคํŠธ๋ฅผ send! ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ

์ค‘์š”ํ•œ ์‚ฌํ•ญ์€ Observable์€ ์‹œํ€€์Šค๋ผ๋Š” ๊ฒƒ์ด๋‹ค. observable์„ ๊ตฌ๋…ํ•œ๋‹ค(subscribing)  ๋Š” ๊ฒƒ์€ Swift Standard library ์—์„œ interator์˜ next()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค

 

        let dog = "๋ฉ๋ฉ"
        let cat = "์•ผ์˜น"
        let bird = "์ท์ท"
        
        let animalSoundObservable = Observable.of(dog, cat, bird)

of ๋กœ Event<String> ์˜ต์ €๋ฒ„๋ธ”์„ ์ƒ์„ฑํ•ด ์ค€๋‹ค! subscribe๋ฅผ ๋ณด๋ฉด 

์ด๋ ‡๊ฒŒ ๋˜์–ด ์žˆ๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Event<String>์„ ๋„˜๊ฒจ์ฃผ๊ณ  Disposable์„ ๋ฐ˜ํ™˜ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค

dispose ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ์ฝ˜์†”์— completed๊ฐ€ ์ฐํžˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹น ๊ทธ๋ž˜๋„ ๋…ธ๋ž€์ค„ ์ง€์›Œ ์ฃผ๋ ค๊ณ  ์•„์ง ์ž˜ ๋ชจ๋ฅด๋Š” DisposeBag()๋กœ ์˜ต์ €๋ฒ„๋ฅผ ์ข…๋ฃŒ์‹œํ‚ค๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค

        let disposebag = DisposeBag()
        
        animalSoundObservable.subscribe { event in
            print(event)
        }.disposed(by: disposebag)

๊ทธ๋Ÿฌ๋ฉด ์ด์ œ ์˜ต์ €๋ฒ„์˜ ๊ฐ ์š”์†Œ๋ฅผ ์ฝ˜์†”์— ํ”„๋ฆฐํŠธ ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์•ž์—์„œ ์‚ดํŽด ๋ดค๋“ฏ์ด ์„ธ๊ฐ€์ง€ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋Š”๋ฐ (.next, .completed, .error)

์˜ต์ €๋ฒ„๋ธ”์ด .next ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ .completed ์ด๋ฒคํŠธ๊ฐ€ ๋ฐฉ์ถœ๋˜๊ณ  ์ฆ‰์‹œ ํ•ด๋‹น ์‹œํ€€์Šค๋Š” ์ข…๋ฃŒ ๋˜๋Š” ๊ฒƒ!

๊ทธ๋ ‡๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ of์™€ from์˜ ์ฐจ์ด๋ฅผ ํ…Œ์ŠคํŠธ ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹น

์–ด๋ ˆ์ด๊ฐ€ ์•„๋‹Œ ๊ฐ ์š”์†Œ๋ฅผ ๋„ฃ์–ด์ค€ of ์˜คํผ๋ ˆ์ดํ„ฐ๋Š” ๋ดค์œผ๋‹ˆ  of์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์–ด๋ ˆ์ด๋ฅผ ๋ณด๋‚ด ์ฃผ๋ฉด

 

next(["๋ฉ๋ฉ", "์•ผ์˜น", "์ท์ท"])

completed

 

๊ฐ€ ์ฐํžˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ next๋Š” ํ•œ๋ฒˆ๋งŒ ๋ฐฉ์ถœ (์–ด๋ ˆ์ด ์ „์ฒด์— ๋Œ€ํ•ด) ๊ทธ ํ›„ completed ์ด๋ฒคํŠธ ๋ฐฉ์ถœ

๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ ์ด์ œ from์„ ์ฐ์–ด๋ณด๋ฉด

 

next(๋ฉ๋ฉ)

next(์•ผ์˜น)

next(์ท์ท)

completed

 

of ์˜คํผ๋ ˆ์ดํ„ฐ์— ์š”์†Œ๋ฅผ ๊ฐ๊ฐ ์ ์–ด์ค€ ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค! 

์•„์ง subscribe๋ฅผ ๋‹ค ๋ณด์ง€ ๋ชปํ•ด์„œ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๋ช‡ ๊ฐœ์ธ์ง€ ๋‚ด์šฉ๋ฌผ์ด ๋ญ”์ง€ ์•Œ์ง€ ๋ชปํ•˜๋Š” ์–ด๋ ˆ์ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค! ํƒ€์ž…๋งŒ ์•ˆ๋‹ค ํ•˜๋ฉด from์„ ์“ฐ๋ฉด ๋˜๊ฒ ๊ณ  ๊ฐ๊ฐ์˜ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์•Œ๊ณ  ๋ช‡๊ฐœ ์•ˆ๋œ๋‹ค ํ•˜๋ฉด of๋ฅผ ์“ฐ๋ฉด ๋˜๊ฒ ๋‹ค ์‹ถ๋‹ค.

next()๋กœ ์ฐํžˆ๋Š” ๊ฒƒ์€ ์ด๋ฒคํŠธ๋ฅผ ํ”„๋ฆฐํŠธ ํ•ด์„œ ๊ทธ๋ ‡๊ณ  ๊ฐ’์„ ํ”„๋ฆฐํŠธ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด next ์ด๋ฒคํŠธ์˜ element๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค 

ex> event.element 

 

์ด๋ฒคํŠธ๊ฐ€ ์•„๋‹Œ ์ด๋ฒคํŠธ์˜ ๊ฐ’์„ ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด onNext๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค!

Event<Element>๊ฐ€ ์•„๋‹Œ Element๋ฅผ ํด๋กœ์ €์˜ ๊ฐ’์œผ๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค

 

        animalSoundObservable.subscribe(onNext: { element in
            print(element)
        })

์ฝ˜์†”์„ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ์ง€๋งŒ completed ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ ˆ๋Œ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ฆ‰ completed, error ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ never ์˜คํผ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

์–ด๋– ํ•œ ์•„์ดํ…œ๋„ ๋ฐฉ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ˆ๋Œ€ ์ข…๋ฃŒ๋˜์ง€๋„ ์•Š๋Š” ์˜ต์ €๋ฒ„๋ธ”์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. 

        let neverObservable = Observable<Any>.never()
        neverObservable.subscribe(onNext: { element in
            print(element)
        }, onCompleted: {
            print("never observable completed") // ์ถœ๋ ฅ์•ˆ๋จ
        })

onCompleted ๊ตฌ๋ฌธ์— ์ ์€ ๋ฌธ๊ตฌ๊ฐ€  ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ never ์˜คํผ๋ ˆ์ดํ„ฐ๋Š” ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š” ์˜ต์ €๋ฒ„๋ธ”์„ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ! ๊ทธ๋ฆฌ๊ณ  ์–ด๋– ํ•œ element๋„ ์—†๋‹ค

 

๊ทธ๋ ‡๋‹ค๋ฉด ๋ฐฉ์ถœ๋˜๋Š” element๋Š” ์—†์ง€๋งŒ ์ฆ‰์‹œ ์ข…๋ฃŒ๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š”  empty ์˜คํผ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค! ์–ด๋””์— ์“ฐ์ด๋Š”์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ์Œ

        let emptyObservable = Observable<Void>.empty()
        emptyObservable.subscribe(onNext: { event in
            print(event)
        }, onCompleted: {
            print("completed")
        }).disposed(by: disposebag)

์ฆ‰์‹œ ์ข…๋ฃŒ๋˜์–ด ์ฝ˜์†”์— completed๊ฐ€ ์ฐํžˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜์žˆ๋‹น

(๊ถ๊ธˆํ•œ๊ฑด ๋ฐ˜ํ™˜๋˜๋Š” element๊ฐ€ ์—†๋‹ค๊ณ  ํ•˜๋Š”๋ฐ ์ด๊ฒƒ์ด nil์„ ์˜๋ฏธํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์™„์ „ํžˆ ๋ฌด์˜ ์ƒํƒœ๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฑฐ๊ฒ ์ง€?? )

 

range๋Š” for๋ฌธ ์ฒ˜๋Ÿผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹น

        let rangeObservable = Observable<Int>.range(start: 1, count: 10)
        rangeObservable.subscribe(onNext: { i in
            print("ํ˜„์žฌ ๊ฐ’์€? : \(i)")
        })

์ฐธ๊ณ  ๋„์„œ : RxSwift reactive programming with swift - raywenderlich

 

๋ฌธ์ œ์‹œ ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ ๋‹ค๋ณด๋‹ˆ ํ‹€๋ฆฐ ๋‚ด์šฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ใ… ใ… 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€