RxSwift
๐๏ธ Swift ์ธ์ด๋ก ์์ฑ๋ ํจ์ํ ๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ์ต์ ๋ฒ๋ธ ์ํ์ค์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ฐํธํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก ์ง์ํ๋ค.
RxSwift ์ด๋?
ReactiveX(Reactive Extensions) ํจํด์ Swift ๋ฒ์ ์ผ๋ก, Swift ์ธ์ด๋ก ์์ฑ๋ ๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
RxSwift๋ ๋ฐ์ดํฐ ์คํธ๋ฆผ๊ณผ ์ด๋ฅผ ๋ค๋ฃจ๋ ์ฐ์ฐ์๋ค์ ํตํด ๋น๋๊ธฐ ๋ฐ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ์ ์ง์ํ๋ค.
- Observable:
- ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ํ๋ด๋ ํ์ ์ผ๋ก, ๋ฐ์ดํฐ์ ๋ณํ๋ ์ด๋ฒคํธ๋ฅผ ๋ฐฉ์ถ(emit)ํ๋ค.
- Observable์ ์ด๋ฒคํธ ์ํ์ค๋ฅผ ๋ฐ์์ํค๋๋ฐ ์ฌ์ฉ๋๋ค.
- ์ด ์ด๋ฒคํธ๋ next, error, completed์ ๊ฐ์ ์ข ๋ฅ๊ฐ ์๋ค.
- Observer:
- Observable์์ ๋ฐฉ์ถ๋ ๋ฐ์ดํฐ๋ ์ด๋ฒคํธ์ ๋ฐ์ํ๋ ๊ฐ์ฒด๋ก, ์ด๋ฅผ ๊ตฌ๋ (subscribe)ํ์ฌ ๋ฐ์ดํฐ์ ๋ณํ๋ฅผ ๊ฐ์ํ๊ณ ์ฒ๋ฆฌํ๋ค.
- Operator:
- Observable์ ๋ณํํ๊ฑฐ๋ ์กฐ์ํ๋ ํจ์๋ก, ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์กฐ์ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
- RxSwift์๋ ๋ง์ ๋ค์ํ ์ฐ์ฐ์๋ค์ด ํฌํจ๋์ด ์์ด์ ๋ฐ์ดํฐ๋ฅผ ํํฐ๋งํ๊ฑฐ๋ ๋ณํ, ๊ฒฐํฉ, ์กฐ์ํ๋ ๋ฑ์ ์์ ์ ์ํํ ์ ์๋ค.
- Schedulers:
- ๋น๋๊ธฐ ์ฝ๋์ ์คํ์ ๊ด๋ฆฌํ๋๋ฐ ์ฌ์ฉ๋๋ฉฐ, ์์ ์ด ์ด๋ ์ค๋ ๋์์ ์คํ๋๋์ง ์ ์ดํ๋ค.
- ๋ฉ์ธ ์ค๋ ๋์์ UI ์ ๋ฐ์ดํธ๋ฅผ ์ํํ๊ฑฐ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ์์ ์ ์ํํ๋ ๋ฑ์ ์ผ์ ์ค์ผ์ค๋งํ ๋ ์ฌ์ฉ๋๋ค.
library
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Library)๋ ํ๋ก๊ทธ๋๋ฐ์์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋ ๋ชจ์์ ๋งํ๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ํน์ ๊ธฐ๋ฅ์ ์ํํ๋ ์ฝ๋์ ๋ชจ์์ด๋ฉฐ, ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ด๋ ํ๋ก์ ํธ์์ ์ฌ์ฉํ ์ ์๋๋ก ์ค๊ณ๋์ด ์๋ค.
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ๋ณต์ ์ด๊ณ ํ์คํ๋ ์์ ์ ์ํํ๋ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ ์๊ฐ์ ๋จ์ถํ๊ณ ํจ์จ์ ์ธ ๊ฐ๋ฐ์ ํ ์ ์๋ค.
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ค์ํ ํํ์ ๋ชฉ์ ์ผ๋ก ์ ๊ณต๋๋ค:
- ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Standard Library): ๋๋ถ๋ถ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค. ์ด๋ ์ธ์ด ์์ฒด์์ ์ ๊ณตํ๋ ๊ธฐ๋ณธ ํจ์, ์๋ฃ๊ตฌ์กฐ, ํ์ผ ์ ์ถ๋ ฅ, ๋ฌธ์์ด ์ฒ๋ฆฌ ๋ฑ์ ๊ธฐ๋ฅ์ ํฌํจํ๋ค. ์๋ฅผ ๋ค์ด, Swift์ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Swift ์ธ์ด์ ํจ๊ป ์ ๊ณต๋๋ ๊ธฐ๋ณธ ๊ธฐ๋ฅ๋ค์ ํฌํจํ๋ค.
- ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Third-party Library): ๊ฐ์ธ์ด๋ ์กฐ์ง์ด ๊ฐ๋ฐํ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ๋ค๋ฅธ ํ๋ก๊ทธ๋๋จธ๋ค์ด ์ฌ์ฉํ ์ ์๋๋ก ๊ณต๊ฐ๋์ด ์๋ค. ๋คํธ์ํน, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, UI ๊ตฌ์ฑ ์์, ์ด๋ฏธ์ง ์ฒ๋ฆฌ, ์ํธํ, ๋ฐ์ดํฐ ๋ถ์ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ๋๋ถ๋ถ์ ์ธ์ด์์๋ ํด๋น ์ธ์ด๋ ํ๋ซํผ์ ๋ง๋ ๋ค์ํ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์กด์ฌํ๋ค.
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ณดํต ํจ์, ํด๋์ค, ๋ชจ๋, ํ๋ ์์ํฌ ํํ๋ก ์ ๊ณต๋๋ฉฐ, ์ด๋ฅผ ํ๋ก์ ํธ์ ์ถ๊ฐํ๊ณ ํ์ฉํ์ฌ ๊ฐ๋ฐ์๊ฐ ์ง์ ํด๋น ๊ธฐ๋ฅ์ ๊ตฌํํ์ง ์์๋ ๋๋ค. ์ด๋ฌํ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋๋ค์ ํจ์จ์ ์ธ ๊ฐ๋ฐ๊ณผ ์ ์ง๋ณด์๋ฅผ ๋์์ค๋ค.
Dependency Manager(์์กด์ฑ ๊ด๋ฆฌ ๋๊ตฌ)
- ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ ๋ค์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ์ธ๋ถ ์์กด์ฑ๋ค์ ๊ด๋ฆฌํ๊ณ ํ๋ก์ ํธ์ ํจ๊ณผ์ ์ผ๋ก ํตํฉํ๊ธฐ ์ํ ๋๊ตฌ
- ์ด๋ฌํ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฝ๊ฒ ๊ฐ์ ธ์ค๊ณ ๋ฒ์ ์ ๊ด๋ฆฌํ๋ฉฐ, ํ๋ก์ ํธ์์ ํ์๋ก ํ๋ ์์กด์ฑ๋ค์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ค.
- ๋ํ์ ์ธ Dependency Manager
- CocoaPods: iOS ๋ฐ macOS ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ Swift/Objective-C ํ๋ก์ ํธ์ ์์กด์ฑ์ ๊ด๋ฆฌํ๋ ๋๊ตฌ. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฝ๊ฒ ๊ฐ์ ธ์ฌ ์ ์๊ณ , ํ๋ก์ ํธ ์ค์ ์ ๊ฐ์ํํ ์ ์๋ค.
- Carthage: CocoaPods์ ์ ์ฌํ์ง๋ง, ํ๋ ์์ํฌ์ ๋น๋๋ฅผ ์ฌ์ฉํ์ฌ ์์กด์ฑ์ ๊ด๋ฆฌํ๋ค. ๋น๋๋ ํ๋ ์์ํฌ๋ฅผ ํ๋ก์ ํธ์ ์๋์ผ๋ก ์ถ๊ฐํด์ผ ํ๋ค.
- Swift Package Manager (SPM): Swift ํ๋ก์ ํธ์ ํจํค์ง ์์กด์ฑ์ ๊ด๋ฆฌํ๋ ๊ณต์์ ์ธ Swift ๋๊ตฌ. ์ ํ์ ๊ณต์ ์ง์์ ๋ฐ๊ณ ์์ผ๋ฉฐ, Swift-only ํ๋ก์ ํธ์์ ์ฌ์ฉ๋๋ค.
RxSwift ์ฌ์ฉ๋ฒ
- Xcode - File - New - Project
- Product Name ์ ๋ ฅ
- CocoaPod ์ค์น
- Podfile ์์ฑ
- Podfile ํธ์ง(vi Podfile)
- pod install
- .xcworkspace ํ์ผ ์คํ → ํ๋ก์ ํธ ๋ด๋ถ์์ Playground ์์ฑ
RxSwift ์์
// 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
*/
// swift์ 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
*/
// RxSwift์ ์์
import Foundation
import RxSwift
import RxCocoa
class DataModel {
let textValueSubject = BehaviorSubject<String>(value: "")
var textValue: Observable<String> {
return textValueSubject.asObservable()
}
}
let dataModel = DataModel()
let disposable = dataModel.textValue.subscribe(onNext: { newValue in
print("Value changed to: \(newValue)")
})
dataModel.textValueSubject.onNext("Hello, RxSwift!")
dataModel.textValueSubject.onNext("Another value")
/*
์ถ๋ ฅ
Value changed to:
Value changed to: Hello, RxSwift!
Value changed to: Another value
*/
- DataModel ํด๋์ค๋ BehaviorSubject๋ฅผ ์ฌ์ฉํ์ฌ textValueSubject๋ฅผ ์ด๊ธฐํํ๊ณ , ์ด๋ฅผ textValue์ Observable๋ก ๋ฐํํฉ๋๋ค.
- let disposable = dataModel.textValue.subscribe(onNext: { newValue in ... })์์ subscribe ๋ฉ์๋๋ textValue์ Observable์ ๊ตฌ๋ ํ๊ณ , ๊ฐ์ ๋ณ๊ฒฝ์ด ์์ ๋๋ง๋ค onNext ํด๋ก์ ๋ด์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค.
- dataModel.textValueSubject.onNext("Hello, RxSwift!")๋ textValueSubject์ onNext๋ฅผ ํธ์ถํ์ฌ "Hello, RxSwift!"๋ฅผ ๋ฐฉ์ถํฉ๋๋ค. ์ด๋ก ์ธํด ๊ตฌ๋ ์ค์ธ subscribe์์ "Value changed to: Hello, RxSwift!"๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
- dataModel.textValueSubject.onNext("Another value")๋ ๋์ผํ ๋ฐฉ์์ผ๋ก ๊ฐ์ ๋ณ๊ฒฝ๊ณผ ํด๋น ๋ณ๊ฒฝ ์ฌํญ์ ๋ํ ์ถ๋ ฅ์ ์งํํฉ๋๋ค.
'๐ Today I Learned > Swift ๋ฌธ๋ฒ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ (1) | 2024.01.03 |
---|---|
[Swift] Alert ์๋ฆผ์ฐฝ ๋์ฐ๊ธฐ (0) | 2023.12.27 |
[Swift] Combine (0) | 2023.12.15 |
[Swift] ์ ๋ค๋ฆญ (Generic) (0) | 2023.12.13 |
[Swift] ํ์ฅ (Extension) (0) | 2023.12.13 |