[RxSwift] Subject, .scan, RxCocoa, .bind ๊ฐœ๋…
iOS/Swift

[RxSwift] Subject, .scan, RxCocoa, .bind ๊ฐœ๋…

๊ณฐํŠ€๊น€ ๋‹˜์˜ RxSwift 4์‹œ๊ฐ„์— ๋๋‚ด๊ธฐ (์ข…ํ•ฉํŽธ) ์˜์ƒ์„ ๋ณด๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ^~^

https://youtu.be/w5Qmie-GbiA

 

์ •๋ง ์ƒ์ดˆ๋ณด,, ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅด๋Š” ์ž…์žฅ์—์„œ ๊ฐ•์˜ ์˜์ƒ์„ ๋ณด๊ณ  ์˜์‹์˜ ํ๋ฆ„๋Œ€๋กœ ์ž‘์„ฑํ•œ ๊ธ€์ด๋‹ˆ ๋น„ํŒ์˜ ๋ˆˆ์œผ๋กœ ๊ธ€์„ ์ฝ์–ด ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค~~ ์˜ค๋ฅ˜ ์ง€์  ๋Œ€ํ™˜์˜!

Subject


  • Observable ๋ฐ–์—์„œ ๊ฐ’์„ ๋ฐ›์•„ ์™€์„œ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ์Œ
  • ์ข…๋ฅ˜ 4๊ฐœ(docs ์ฐธ๊ณ )
    • AsyncSubject
    •  
      • Subcribe๊ฐ€ ์•„๋ฌด๋ฆฌ ๋งŽ์ด ๋“ค์–ด์™€๋„ Complete ์‹œ์ ์— ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ๋งŒ ๋ชจ๋‘์—๊ฒŒ ๋‚ด๋ ค ์คŒ
    • BehaviorSubject
    •  
      • ๊ธฐ๋ณธ๊ฐ’ ํ•˜๋‚˜ ๊ฐ€์ง€๊ณ  ์‹œ์ž‘, ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ Subscribeํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’์„ ๋‚ด๋ ค ์คŒ
      • ์ค‘๊ฐ„์— ์ƒˆ๋กญ๊ฒŒ Subscirbe๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์˜ ๊ฐ’์„ ๋‚ด๋ ค ์คŒ
    • PublishSubject
    •  
      • Subscribe๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๊ทธ๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ ค ์คŒ
      • ์ค‘๊ฐ„์— ์ƒˆ๋กญ๊ฒŒ Subscribe๊ฐ€ ๋“ค์–ด์™€๋„ ๊ทธ ์ค‘๊ฐ„๋ถ€ํ„ฐ ๊ทธ๋Œ€๋กœ ๋‚ด๋ ค ์คŒ
    • ReplaySubject
    •  
      • ์ฒ˜์Œ๋ถ€ํ„ฐ Subscribeํ•˜๋ฉด PublishSubject์™€ ๋˜‘๊ฐ™์ด ๋ฐ์ดํ„ฐ ๋‚ด๋ ค ์คŒ
      • ์ค‘๊ฐ„์— Subscribe๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๊ทธ๋™์•ˆ์˜ ๋ฐ์ดํ„ฐ๋“ค์„ ํ•œ๋ฒˆ์— Replayํ•˜์—ฌ ๋‚ด๋ ค ์คŒ

Sugar API


.scan

  • ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๊ณ„์† ๋ˆ„์ ์‹œํ‚ด
  • [Scan] โ€” Observable์ด ๋ฐฐ์ถœํ•œ ํ•ญ๋ชฉ์— ์—ฐ์†์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹คํ–‰ํ•œ ํ›„ ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋œ ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ๊ฐ’์„ ๋ฐœํ–‰ํ•œ๋‹ค
  • ์ดˆ๊ธฐ๊ฐ’-1๋ฒˆ ์—ฐ์‚ฐํ•˜์—ฌ ๋ฆฌํ„ด(A), A-2๋ฒˆ ์—ฐ์‚ฐํ•˜์—ฌ ๋ฆฌํ„ด(B), B-3๋ฒˆ ์—ฐ์‚ฐํ•˜์—ฌ ๋ฆฌํ„ด(C), C-4๋ฒˆ ์—ฐ์‚ฐํ•˜์—ฌ ๋ฆฌํ„ด(D) ...
  • ์ดˆ๊ธฐ๊ฐ’๊ณผ ์—ฐ์‚ฐ
    • .scan์— ๋“ค์–ด์˜ฌ ์ฒซ ๋ฒˆ์งธ ๊ฐ’์€ ์ดˆ๊ธฐ๊ฐ’๊ณผ ์—ฐ์‚ฐ๋จ!
Observable.of(1, 2, 3) // ๋งŒ์•ฝ 1, 2, 3์ด ์—ฐ์†์œผ๋กœ ๋“ค์–ด์˜จ๋‹ค๋ฉด
   .scan(0) { (prevValue, newValue) in // ์ดˆ๊ธฐ๊ฐ’์„ 0์œผ๋กœ!
      return prevValue + newValue
   }
   .subscribe(onNext: { print($0) })
// ๊ฒฐ๊ณผ
1 // (์ดˆ๊ธฐ๊ฐ’ 0 + 1)
3 // (๊ธฐ์กด๊ฐ’ 1 + 2)
6 // (๊ธฐ์กด๊ฐ’ 3 + 3)

RxCocoa


  • Rx๋ฅผ ํ™œ์šฉํ•œ UIKit์˜ Extension ์ œ๊ณต
  • Sugar API
    • .bind ์ˆœํ™˜ ์ฐธ์กฐ ์—†์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ( .subscribe์™€ ๋™์ผ)
    • .bind (2:25:25~)
    • UIKit์š”์†Œ.rx.~ ํ–ˆ์„ ๋•Œ ๋‚˜์˜ค๋Š” ๊ฐ’์ด Binder๋ฉด ๋ฐ”์ธ๋“œ๋ฅผ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ
    • Subscirbe๋ฅผ ํ•˜์ง€ ์•Š๊ณ  bindํ•ด์„œ ์‚ฌ์šฉ
    • .map { "\($0)" }
      .bind(to: itemCountLabel.rx.text)
      .disposed(by: disposeBag)
    • .subscribe(onNext: [weak self] {
      	self.itemCountLabel.text = $0
      })
      .disposed(by: disposeBag)
    • ์œ„์˜ ๋‘ ์ฝ”๋“œ๊ฐ€ ๊ฐ™์€ ๋™์ž‘!
    • ์žฅ์ : [weak self] ๊ฐ™์€ ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐฉ์ง€๋ฅผ ์•ˆ ํ•ด๋„ ๋จ
    • ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ UI๋ฅผ ๋ฐ”๊พธ๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋ ค๋ฉด ๋ฉ”์ธ ์Šค์ผ€์ค„๋Ÿฌ์—์„œ ๋™์ž‘์‹œ์ผœ์•ผ ํ•จ!
    • .map { "\($0)" }
      .observeOn(MainScheduler.instance)
      .bind(to: itemCountLabel.rx.text)
      .disposed(by: disposeBag)