λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
🍏 Today I Learned/Swift 문법

[Swift] Combine

by Joseph Seong 2023. 12. 15.

 

 

Combine

 

πŸ–οΈ Swiftμ—μ„œ μ œκ³΅ν•˜λŠ” ν•¨μˆ˜ν˜• λ°˜μ‘ν˜• ν”„λ‘œκ·Έλž˜λ°μ„ μœ„ν•œ ν”„λ ˆμž„μ›Œν¬λ‘œ, 비동기적인 데이터 μŠ€νŠΈλ¦Όμ„ 닀루고 μ‘°μž‘ν•˜λŠ”λ° μ‚¬μš©λœλ‹€.

 

 

λ°˜μ‘ν˜• ν”„λ‘œκ·Έλž˜λ°μ΄λž€?

 

λ°˜μ‘ν˜• ν”„λ‘œκ·Έλž˜λ°(Reactive Programming)은 데이터 슀트림 λ˜λŠ” λ°μ΄ν„°μ˜ 변화에 따라 μ½”λ“œκ°€ μžλ™μœΌλ‘œ λ°˜μ‘ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μ΄λ‹€. 이 νŒ¨λŸ¬λ‹€μž„μ—μ„œλŠ” λ°μ΄ν„°μ˜ λ³€κ²½ 사항을 κ°μ§€ν•˜κ³  이에 따라 μ—°μ†μ μœΌλ‘œ λ°˜μ‘ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•œλ‹€.

λ°˜μ‘ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ λ‹€μŒκ³Ό 같은 핡심 κ°œλ…μ„ ν¬ν•¨ν•˜κ³  μžˆλ‹€.

 

1. 데이터 슀트림(Data Stream):

  • 이벀트 슀트림, κ°’μ˜ 흐름 λ“±κ³Ό 같이 μ‹œκ°„μ— 따라 μ—°μ†μ μœΌλ‘œ λ°œμƒν•˜λŠ” λ°μ΄ν„°μ˜ 흐름을 λ‚˜νƒ€λ‚Έλ‹€.
  • μ΄λŸ¬ν•œ 데이터 μŠ€νŠΈλ¦Όμ€ μ‚¬μš©μž μž…λ ₯, μ„Όμ„œ 데이터, μ™ΈλΆ€ API의 응닡 λ“± λ‹€μ–‘ν•œ μ†ŒμŠ€μ—μ„œ λ‚˜μ˜¬ 수 μžˆλ‹€.

2. μ˜΅μ €λ²„(Observer) νŒ¨ν„΄:

  • λ°μ΄ν„°μ˜ λ³€ν™”λ₯Ό κ°μ‹œν•˜κ³ , 변화에 따라 νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λ””μžμΈ νŒ¨ν„΄μ΄λ‹€.
  • λ³€ν™”κ°€ μΌμ–΄λ‚˜λ©΄ μ˜΅μ €λ²„(λ˜λŠ” κ΅¬λ…μž)λŠ” ν•΄λ‹Ή 변화에 λ°˜μ‘ν•˜μ—¬ μ•Œλ¦Όμ„ λ°›κ³ , ν•„μš”ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.

3. 슀트림의 λ³€ν™˜κ³Ό μ‘°μž‘(Transforming and Manipulating Streams):

  • 데이터 μŠ€νŠΈλ¦Όμ„ μ‘°μž‘ν•˜μ—¬ 필터링, λ§€ν•‘, κ²°ν•©, λ³€ν™˜ 등을 μˆ˜ν–‰ν•˜μ—¬ μƒˆλ‘œμš΄ μŠ€νŠΈλ¦Όμ„ μƒμ„±ν•˜λŠ” μž‘μ—…μ΄λ‹€.
  • 이λ₯Ό 톡해 데이터 μŠ€νŠΈλ¦Όμ„ 효과적으둜 μ²˜λ¦¬ν•˜κ³  ν•„μš”ν•œ ν˜•νƒœλ‘œ 가곡할 수 μžˆλ‹€.

4. 바인딩(Binding):

  • λ°μ΄ν„°μ˜ 변화와 이에 λ”°λ₯Έ μž‘μ—…μ˜ 연결을 λ‚˜νƒ€λ‚Έλ‹€.
  • 데이터와 UI μš”μ†Œ, λ˜λŠ” 데이터와 μž‘μ—… μ‚¬μ΄μ˜ 연결을 μ„€μ •ν•˜μ—¬, λ°μ΄ν„°μ˜ 변경이 λ°œμƒν•˜λ©΄ 이에 맞좰 UIλ‚˜ λ‹€λ₯Έ μž‘μ—…μ„ μžλ™μœΌλ‘œ μ—…λ°μ΄νŠΈν•œλ‹€.
  • 바인딩은 λ°μ΄ν„°μ˜ 변화와 μ—°κ΄€λœ μž‘μ—…μ΄ μ„œλ‘œ κ²°ν•©λ˜μ–΄ μžˆμ–΄μ„œ, ν•˜λ‚˜μ˜ λ³€ν™”κ°€ λ‹€λ₯Έ μž‘μ—…μ— μžλ™μœΌλ‘œ μ „λ‹¬λ˜κ³  반영될 수 μžˆλ„λ‘ ν•΄μ€€λ‹€. 이λ₯Ό 톡해 μ½”λ“œμ˜ 가독성과 μœ μ§€λ³΄μˆ˜μ„±μ„ 높일 수 μžˆλ‹€.
  • λ§Žμ€ ν”„λ ˆμž„μ›Œν¬μ™€ λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ΄ λ°˜μ‘ν˜• ν”„λ‘œκ·Έλž˜λ°μ„ μ§€μ›ν•˜λ©°, Swiftμ—μ„œλŠ” Combine ν”„λ ˆμž„μ›Œν¬κ°€ μ΄λŸ¬ν•œ κ°œλ…μ„ ν¬ν•¨ν•˜κ³  μžˆμ–΄ 데이터 슀트림의 λ³€ν™”λ₯Ό μ‰½κ²Œ μ²˜λ¦¬ν•˜κ³  λ°˜μ‘ν˜•μœΌλ‘œ ν”„λ‘œκ·Έλž˜λ°ν•  수 μžˆλ‹€.

 

 

Combine μ΄λž€?

 

Combine은 Apple의 Swift ν”„λ‘œκ·Έλž˜λ° 언어에 ν¬ν•¨λœ ν”„λ ˆμž„μ›Œν¬λ‘œ, 비동기적인 이벀트 μŠ€νŠΈλ¦Όμ„ μ²˜λ¦¬ν•˜κ³  μ‘°μž‘ν•˜λŠ” 데 μ‚¬μš©λœλ‹€. μ΄λŠ” ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°κ³Ό λ°˜μ‘ν˜• ν”„λ‘œκ·Έλž˜λ° κ°œλ…μ„ 기반으둜 ν•˜λ©°, 데이터 μŠ€νŠΈλ¦Όμ„ κ°„λ‹¨ν•˜κ²Œ μ‘°μž‘ν•˜κ³  μ‘°ν•©ν•  수 μžˆλŠ” 도ꡬλ₯Ό μ œκ³΅ν•œλ‹€.

  1. Publisher(λ°œν–‰μž):
    • 데이터 μŠ€νŠΈλ¦Όμ„ μƒμ„±ν•˜κ³ , 이벀트λ₯Ό λ°©μΆœν•˜λŠ” νƒ€μž…
    • 값을 λ°©μΆœν•  수 있으며, 였λ₯˜λ₯Ό λ°©μΆœν•˜κ±°λ‚˜ μž‘μ—…μ΄ μ™„λ£Œλ˜μ—ˆμŒμ„ μ•Œλ¦΄ 수 μžˆλ‹€.
  2. Subscriber(κ΅¬λ…μž):
    • Publisherμ—μ„œ λ°©μΆœλ˜λŠ” 이벀트λ₯Ό λ°›μ•„ μ²˜λ¦¬ν•˜λŠ” νƒ€μž…
    • 값을 λ°›μ•„ μ²˜λ¦¬ν•˜κ±°λ‚˜, 였λ₯˜λ‚˜ μž‘μ—… μ™„λ£Œ 이벀트λ₯Ό μ²˜λ¦¬ν•œλ‹€.
  3. Operators(μ—°μ‚°μž):
    • Combine ν”„λ ˆμž„μ›Œν¬μ—λŠ” 데이터 μŠ€νŠΈλ¦Όμ„ μ‘°μž‘ν•˜κ³  λ³€ν™˜ν•˜κΈ° μœ„ν•œ λ‹€μ–‘ν•œ μ—°μ‚°μžκ°€ μ œκ³΅λœλ‹€.
    • map, filter, flatMap λ“±μ˜ μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터 μŠ€νŠΈλ¦Όμ„ μ‘°μž‘ν•˜κ³  μƒˆλ‘œμš΄ ν˜•νƒœλ‘œ λ³€ν™˜ν•  수 μžˆλ‹€.
  4. Cancellable(μ·¨μ†Œ κ°€λŠ₯ν•œ):
    • Combineμ—μ„œλŠ” ꡬ독을 μ·¨μ†Œν•  수 μžˆλŠ” νƒ€μž…μΈ Cancellable이 μ œκ³΅λœλ‹€.
    • ꡬ독을 μ·¨μ†Œν•¨μœΌλ‘œμ¨ 더 이상 이벀트λ₯Ό λ°›μ§€ μ•Šλ„λ‘ μ„€μ •ν•  수 μžˆλ‹€.

 

Combine μ˜ˆμ‹œ

 

// swift μ˜ˆμ‹œ
import Foundation

class DataModel {
    var textValue: String = ""

    func updateText(to newValue: String) {
        textValue = newValue
        print("Value updated: \(textValue)")
    }
}

let dataModel = DataModel()

dataModel.updateText(to: "Hello, Swift!")
dataModel.updateText(to: "Another value")

/*
좜λ ₯
Value changed to: Hello, Swift!
Value changed to: Another value
*/

// didset을 μ΄μš©ν•œ μ˜ˆμ‹œ
class DataModel {
    var textValue: String = "" {
        didSet {
            print("Value updated: \(textValue)")
        }
    }
}

let dataModel = DataModel()

func changeText(to newValue: String) {
    dataModel.textValue = newValue
}

changeText(to: "Hello, Swift!")
changeText(to: "Another value")

/*
좜λ ₯
Value changed to: Hello, Swift!
Value changed to: Another value
*/

// combine μ˜ˆμ‹œ
import Foundation
import Combine

class DataModel {
    @Published var textValue: String = ""
}

let dataModel = DataModel()

let cancellable = dataModel.$textValue.sink { newValue in
    print("Value changed to: \(newValue)")
}

dataModel.textValue = "Hello, Combine!"
dataModel.textValue = "Another value"

/*
좜λ ₯
Value changed to: 
Value changed to: Hello, Combine!
Value changed to: Another value
*/

 

  1. DataModel ν΄λž˜μŠ€λŠ” @Published ν”„λ‘œνΌν‹° 래퍼λ₯Ό μ‚¬μš©ν•˜μ—¬ textValueλ₯Ό μ„ μ–Έν–ˆλ‹€. 
    1. @Published ν”„λ‘œνΌν‹° λž˜νΌλŠ” 값이 변경될 λ•Œλ§ˆλ‹€ ν•΄λ‹Ή κ°’μ˜ λ³€κ²½ 사항을 κ²Œμ‹œ(publish)ν•œλ‹€.
  2. let cancellable = dataModel.$textValue.sink { newValue in ... }μ—μ„œ $textValueλŠ” textValue의 Publisherλ₯Ό λ‚˜νƒ€λ‚Έλ‹€. sink μ—°μ‚°μžλŠ” 이 Publisherλ₯Ό ꡬ독(subscribe)ν•˜κ³ , κ°’μ˜ λ³€κ²½ 사항이 μžˆμ„ λ•Œλ§ˆλ‹€ ν΄λ‘œμ € λ‚΄μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•œλ‹€.
  3. dataModel.textValue = "Hello, Combine!" μ½”λ“œλŠ” textValue의 값을 λ³€κ²½ν•˜κ³ , 이둜 인해 sink ν΄λ‘œμ € λ‚΄μ˜ μ½”λ“œκ°€ μ‹€ν–‰λ˜μ–΄ "Value changed to: Hello, Combine!"λ₯Ό 좜λ ₯ν•œλ‹€.
  4. dataModel.textValue = "Another value"도 λ™μΌν•œ λ°©μ‹μœΌλ‘œ κ°’μ˜ λ³€κ²½κ³Ό ν•΄λ‹Ή λ³€κ²½ 사항에 λŒ€ν•œ 좜λ ₯을 μ§„ν–‰ν•œλ‹€.

 

 

 

 

 

 

'🍏 Today I Learned > Swift 문법' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[Swift] Alert μ•Œλ¦Όμ°½ λ„μš°κΈ°  (0) 2023.12.27
[Swift] RxSwift  (0) 2023.12.15
[Swift] μ œλ„€λ¦­ (Generic)  (0) 2023.12.13
[Swift] ν™•μž₯ (Extension)  (0) 2023.12.13
[Swift] ν”„λ‘œν† μ½œ  (0) 2023.12.13