iOS/πŸ” RxSwift ⁄ Combine

[RxSwift] Observables

woozzang 2021. 12. 20. 09:50

참고자료

  • KxCoding
  • rayWendelich

 

λͺ©ν‘œ

  • Observable 의 νŠΉμ§•μ€?
  • Observable 을 λ§Œλ“œλŠ” 두 가지 방법을 μ΄ν•΄ν•œλ‹€
  • Observable 을 μ‚¬μš©ν•˜λŠ” 방법을 μ΄ν•΄ν•œλ‹€

 

μ˜΅μ €λ²„λΈ”μ΄ λ­”κ°€μš”?

Rx 의 심μž₯ πŸ’—

  • Rx μ—μ„œ λͺ¨λ“  것은:
    • μ‹œν€€μŠ€ μ΄κ±°λ‚˜
    • μ‹œν€€μŠ€μ™€ ν•¨κ»˜ λ™μž‘ν•˜λŠ” 것듀

 

Observable, Observable sequence, Sequence λŠ” λͺ¨λ‘ μ˜΅μ €λ²„λΈ”μ„ κ°€λ¦¬ν‚€λŠ” 말

  • μ‹œν€€μŠ€μΈλ° 비동기 μ‹œν€€μŠ€μ΄λ‹€.
  • μ‹œν€€μŠ€λŠ” 일정 κΈ°κ°„ (μœ ν•œ ~ λ¬΄ν•œ) λ™μ•ˆ 이벀트λ₯Ό μƒμ‚°ν•œλ‹€.
  • 이것을 이벀트λ₯Ό λ°©μΆœν•œλ‹€κ³  ν‘œν˜„ν•œλ‹€.
  • μ˜΅μ €λ²„λΈ”μ€ μ˜΅μ €λ²„κ°€ κ΅¬λ…ν•œλ‹€.

 

이벀트의 λ°©μΆœμ€ 특히 λ§ˆλΈ” λ‹€μ΄μ–΄κ·Έλž¨μœΌλ‘œ μ΄ν•΄ν•˜λ©΄ νŽΈν•˜λ‹€:

  • μ‹œκ°„μ€ μ™Όμͺ½μœΌλ‘œ 였λ₯Έμͺ½μœΌλ‘œ 흐λ₯Έλ‹€ ⏰
    • λ§ˆλΈ” κ°„ 간격이 νŠΉμ •ν•œ μ‹œκ°„μ˜ 크기λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 것은 μ•„λ‹ˆλ‹€
    • 이벀트 μ „ ν›„ 관계λ₯Ό ν‘œν˜„ν• λΏ

 

  • ν•˜λ‚˜μ˜ λ§ˆλΈ”μ΄ [ν•˜λ‚˜μ˜ 이벀트] λ₯Ό 가리킨닀
  • κ°€μž₯ 였λ₯Έμͺ½μ— λ³΄μ΄λŠ” vertical bar λŠ” μ‹œν€€μŠ€μ˜ μ’…λ£Œ μ‹œμ μ„ 가리킨닀
    • ❌ λ§ˆν¬λ„ μžˆλŠ”λ° [μ—λŸ¬ 이벀트의 λ°œμƒ] 을 가리킨닀.

Marble Diagrams

 

간단 정리!

  • μ˜΅μ €λ²„λΈ”(μ‹œν€€μŠ€) λŠ” elements (보톡 데이터, μΈμŠ€ν„΄μŠ€) λ₯Ό ν¬ν•¨ν•˜κ³  μžˆλŠ” next μ΄λ²€νŠΈλ₯Ό λ°©μΆœν•œλ‹€!
  • μ˜΅μ €λ²„λΈ”μ€ error κ³Ό completed 이벀트둜 μ’…λ£Œλœλ‹€
  • μ’…λ£Œλœ μ˜΅μ €λ²„λΈ”μ€ 더이상 이벀트λ₯Ό λ°©μΆœν•˜μ§€ μ•ŠλŠ”λ‹€.

 

μ΄λ²€νŠΈλŠ” μ—΄κ±°ν˜•, 3가지 μΌ€μ΄μŠ€λŠ”:

  • next(Element) μ—°κ΄€ κ°’μœΌλ‘œ Obsevable 의 νƒ€μž… νŒŒλΌλ―Έν„°λ‘œ μ •μ˜λœ ν˜•μ‹μ˜ 값이 λ“€μ–΄μžˆλ‹€.
  • error(Swift.Error)completed 와 λ§ˆμ°¬κ°€μ§€λ‘œ 이후 μ‹œν€€μŠ€κ°€ μ’…λ£Œλœλ‹€.
  • Error ν”„λ‘œν† μ½œμ„ μ±„νƒν•œ νƒ€μž…μ˜ 값이 μ—°κ΄€ κ°’μœΌλ‘œ λ“€μ–΄μžˆλ‹€.
  • completedμ‹œν€€μŠ€κ°€ ‘μ„±κ³΅μ μœΌλ‘œ μ’…λ£Œλ˜μ—ˆμŒ’ 을 μ•Œλ¦¬λŠ” 역할도 ν•œλ‹€.
  • μ‹œν€€μŠ€ μ’…λ£Œ μ „ λ§ˆμ§€λ§‰ 이벀트

 

Observables λ₯Ό λ§Œλ“œλŠ” 방법!

  • 단, λ§Œλ“ λ‹€κ³  이벀트λ₯Ό λ°©μΆœν•˜λŠ” 것이 μ•„λ‹˜μ„ κΈ°μ–΅ν•˜μž
  • subscribe ν•΄μ•Ό μ΄λ²€νŠΈκ°€ λ°©μΆœλœλ‹€

 

  1. create λ₯Ό μ‚¬μš©
    • μ–΄λ–€ 이벀트λ₯Ό μ–΄λ–»κ²Œ 전달할지 직접 μ •μ˜ν•΄μ€„ 수 μžˆλ‹€
    • μ˜΅μ €λ²„λΈ”μ€ Disposable 을 λ°˜ν™˜ν•΄μ•Όν•˜λŠ” 것을 μƒκΈ°ν•˜μž
      • return Disposable.create()

 

  1. operator λ₯Ό μ‚¬μš©
    • 이게 νƒ€μž… λ©”μ„œλ“œλž¬λ‚˜ ν•˜μ—¬κ°„ μƒˆλ‘œμš΄ Observablesλ₯Ό λ°˜ν™˜ν•œλ‹€
    • νƒ€μž… λ©”μ„œλ“œλ‘œ λ§Œλ“€ μˆ˜λ„ 있고, μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ‘œ λ§Œλ“€ μˆ˜λ„ μžˆλ‹€.

 

Observable κ΅¬λ…ν•˜κΈ°

  • μ˜΅μ €λ²„λΈ”μ€ κ΅¬λ…μžκ°€ 생기기 μ „κΉŒμ§€ 이벀트λ₯Ό λ°©μΆœν•˜μ§€ μ•ŠλŠ”λ‹€
    • ꡬ독을 μ‹œμž‘λ˜μ–΄μ•Ό 이벀트 λ°©μΆœμ„ μ‹œμž‘ν•œλ‹€

 

  • μ˜΅μ €λ²„λΈ” μžμ²΄λŠ” μ‹œν€€μŠ€μ— λŒ€ν•œ μ •μ˜μΌ 뿐이닀
func subscribe(_ on: @escaping (Event<Int>) -> Void) -> Disposable
  • Event νƒ€μž…μ€ element λΌλŠ” 속성을 가지고 있고, μ΄λ²€νŠΈκ°€ 가지고 μžˆλŠ” μ—°κ΄€ 값이닀.
    • μš°λ¦¬κ°€ μ •λ§λ‘œ κ΄€μ‹¬μžˆλŠ” κ·Έ κ°’
    • μœ„ μ½”λ“œμ—μ„œλŠ” Int νƒ€μž…μ˜ element λ₯Ό 가지고 μžˆλ‹€.
      • μ œλ„€λ¦­μ΄λ―€λ‘œ μ˜΅μ €λ²„λΈ”μ˜ μ •μ˜μ— 따라 μœ μ—°ν•˜κ²Œ λ°”λ€œμ„ μΈμ§€ν•˜μž

 

.empty()

  • 아무 μ΄λ²€νŠΈλ„ λ°©μΆœν•˜μ§€ μ•Šκ³ , λ°”λ‘œ completed μ΄λ²€νŠΈλ₯Ό λ°©μΆœν•˜κ³  μ’…λ£Œλ˜λŠ” μ‹œν€€μŠ€
  • 보톡 Void νƒ€μž…μœΌλ‘œ μ§€μ •ν•œλ‹€
Observable<Void>.never()

.never()

  • 암것도 μ•ˆν•¨ γ…‹γ…‹..

 

Disposing & Terminating

  • subscribe κ°€ μ‹œν€€μŠ€λ₯Ό μ‹œμž‘ν•œλ‹€λ©΄, error 와 completed κ°€ μ‹œν€€μŠ€λ₯Ό μ’…λ£Œ μ‹œν‚¨λ‹€.
  • 그런데 μ‹œν€€μŠ€λ₯Ό μˆ˜λ™μœΌλ‘œ μ’…λ£Œμ‹œν‚€λŠ” λ˜λ‹€λ₯Έ 방법이 μžˆλ‹€.
    • μ‹œν€€μŠ€λ₯Ό μ’…λ£Œμ‹œν‚¨λ‹€ = ꡬ독을 μ·¨μ†Œν•œλ‹€ , μ •λ¦¬ν•œλ‹€ (dispose)

 

  • subscribe λ©”μ„œλ“œλŠ” Disposable νƒ€μž… μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€.
    • 이 νƒ€μž…μ€ dispose λΌλŠ” λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€
    • ν˜ΈμΆœν•˜λ©΄ ꡬ독이 μ·¨μ†Œλœλ‹€!
    • subscription.dispose()

 

  • 일일이 μ΄λ ‡κ²Œ ꡬ독을 κ΄€λ¦¬ν•˜λŠ” 것은 μž₯ν™©ν•˜λ‹€
    • DisposeBag 에 Disposable 듀을 λ„£μ–΄λ§Œ 두면, DisposeBag 이 λ©”λͺ¨λ¦¬ ν•΄μ œλ˜λŠ” μ‹œμ μ— κ΄€λ ¨ μžμ›λ“€μ„ 정리해쀀닀.
    • 이것이 κ°€μž₯ μžμ£Όμ“°λŠ” νŒ¨ν„΄!
    • disposed(by:)
      • disposeBag 이 μ•Œμ•„μ„œ ν•˜λ‚˜μ”© dispose()λ₯Ό ν˜ΈμΆœν•΄μ€„ 것이닀.
    // 1
      let disposeBag = DisposeBag()
    
      // 2
      Observable.of("A", "B", "C")
        .subscribe { // 3
          print($0)
        }
        .disposed(by: disposeBag) // 4
    
    • μ΄λŸ°μ‹μœΌλ‘œ 정리해주지 μ•ŠμœΌλ©΄ λ©”λͺ¨λ¦¬ 릭이 λ°œμƒν•œλ‹€.

 

μ˜΅μ €λ²„λΈ” νŒ©ν† λ¦¬ μƒμ„±ν•˜κΈ°

  • deffered Operator μ‚¬μš©
    • μ²¨λ³΄λŠ”λ””??

 

  • μƒˆλ‘œμš΄ ꡬ독이 μ‹œμž‘λ  λ•Œλ§ˆλ‹€ flip 의 μƒνƒœκ°€ λ³€κ²½λœλ‹€
      let disposeBag = DisposeBag()
    
      // 1
      var flip = false
    
      // 2
      let factory: Observable<Int> = Observable.deferred {
    
        // 3
        flip.toggle()
    
        // 4
        if flip {
          return Observable.of(1, 2, 3)
        } else {
          return Observable.of(4, 5, 6)
        }
      }
    
  • filp 에 따라 λ‹€λ₯Έ μ˜΅μ €λ²„λΈ”μ„ λ°˜ν™˜ν•œλ‹€

 

Traits μ‚¬μš©ν•˜κΈ° ( λ‚˜μ€‘μ— ν•„μš”ν•  λ•Œ μ •λ¦¬ν•˜μž )

Traits λŠ” κΈ°μ‘΄ μ˜΅μ €λ²„λΈ”λ³΄λ‹€ μ œν•œλœ λ™μž‘μ„ μˆ˜ν–‰ν•˜λŠ” μ˜΅μ €λ²„λΈ”μ΄λ‹€.

μ‚¬μš©ν•΄λ„λ˜κ³  μ‚¬μš©ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

μ½”λ“œμ˜ μ˜λ„λ₯Ό λͺ…ν™•ν•˜κ²Œ ν•΄μ€€λ‹€.

  • 직관적인 μ½”λ“œμ˜ μž‘μ„± κ°€λŠ₯

 

μ’…λ₯˜

  • Single
  • Maybe
  • Completable

 

Challenge πŸ”₯

  • do μ—°μ‚°μžμ˜ μ‚¬μš©
    • event 에 영ν–₯을 μ£Όμ§€μ•ŠλŠ” μž‘μ—…μ„ ν•  수 있게 ν•΄μ€€λ‹€
      • 즉, νŒŒλΌλ―Έν„°λŠ” λ”°λ‘œ μ—†λŠ” ν•Έλ“€λŸ¬λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€.
      • onNext, afterNext, onSubscribe λ“± λ‹€μ–‘ν•œ μ‹œμ μ— ν•  μ–΄λ–€ λ™μž‘μ„ μ •μ˜ν•  수 μžˆλ‹€.
    • μ—°μ‚°μžμ΄λ―€λ‘œ μ˜΅μ €λ²„λΈ”μ„ λ°˜ν™˜ν•œλ‹€.

 

  • debug μ—°μ‚°μžμ˜ μ‚¬μš©
    • μ˜΅μ €λ²„λΈ”μ΄ λ°©μΆœν•˜λŠ” 이벀트 정보λ₯Ό λ³Ό 수 μžˆλ‹€!!!!!!!
    • identifier λ₯Ό μ „λ‹¬ν•˜λ©΄ μ–΄λŠ μ˜΅μ €λ²„λΈ”μ—μ„œ λ°œμƒν•˜λŠ” μ΄λ²€νŠΈμΈμ§€ 확인할 수 있기 λ•Œλ¬Έμ— μ’‹λ‹€!!!!
      • 특히 체이닝 μƒν™©μ—μ„œ
    observable
        .debug("ν…ŒμŠ€νŠΈ", trimOutput: false)
        .subscribe(
        onNext: { element in
          print(element)
        },
        onCompleted: {
          print("Completed")
        }
        ).disposed(by: DisposeBag())
    
    • κ²°κ³Ό
    --- Example of: never ---
    2021-12-20 00:36:22.756: ν…ŒμŠ€νŠΈ -> subscribed
    2021-12-20 00:36:22.757: ν…ŒμŠ€νŠΈ -> isDisposed
    


    μ˜€λŠ˜λ„ λ‚˜λŠ” μ„±μž₯ν–ˆλ‹€!!πŸ”₯

     

    πŸ€–πŸŸ’[우짱의 iOS λΈ”λ‘œκ·Έ]πŸ”΅πŸ’»

    iOSλ₯Ό κ³΅λΆ€ν•˜λ©΄μ„œ 배운 λ‚΄μš©μ„ κΈ°λ‘ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.