์๋ ํ์ธ์ ์ ์ธ์ ๋๋ค!
๊ต์ฅํ ์ค๋๋ง์ ๊ธ์ ์ฐ๋๋ฐ... ์ปด๋ฐ์ธ์ผ๋ก ๋์์์ต๋๋ค ใ ...
๋์๋ฆฌ ํ์ ์ผ๋ก ๋ฐ๋น ์ ๋ธ๋ก๊ทธ์ ๊ณต๋ถํ ๋ด์ฉ ์ ๋ฆฌ๋ฅผ ๋ชปํ๋๋ฐ,
๋์๋ฆฌ ํ๊ธฐ๋ ๊ฐ์ ธ์ค๊ณ ๊ทธ๋์ ๊ณต๋ถํ ๋ด์ฉ๋ ์ ๋ฆฌํด์ ์ฌ๋ ค๋ณด๋๋ก ํ ๊ฒ์!
๋์๋ฆฌ ํ์ ์์ SwiftUI + Combine ์ผ๋ก ๊ฐ๋ฐ์ ํ๊ฒ ๋์๋๋ฐ์, ์๋ก์ด ์คํ์ ๋์ ํ๋ ์ฌ๋ฐ์์ต๋๋ค๐
๋ ๊น๊ฒ ๊ณต๋ถํด๋ณด๋ฉด์ ๋ด์ฉ์ ๋ฆฌ๋ฅผ ํด๋ณด๋ ค๊ตฌ์ ! ์ค๋์ ์ปด๋ฐ์ธ ์์ํ๊ธฐ๋ก Publisher์ Subscriber์ ๋ํด ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
Combine ์ด๋?
Combine์ Apple์์ ๊ณต์์ ์ผ๋ก ์ ๊ณตํ๋ ๋น๋๊ธฐ ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ฅผ ์ํ ํ๋ ์์ํฌ์ ๋๋ค.
๋ ๋ค๋ฅธ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋๊ตฌ์ธ RxSwift๋ third-party ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด์ง๋ง Combine์ Apple์์ ๊ณต์์ ์ผ๋ก ์ ๊ณตํด์ฃผ๋ ํ๋ ์์ํฌ๋ก, 2019๋ ์ ๊ณต๊ฐ๋์ด iOS 13 ์ด์๋ถํฐ ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค!
๊ณต์๋ฌธ์์ ์๊ฐ๋ฅผ ๋ฒ์ญํด๋ณด๋ฉด,
Combine์ ์ด๋ฒคํธ ์ฒ๋ฆฌ ์ฐ์ฐ์๋ฅผ ๊ฒฐํฉํ์ฌ ๋น๋๊ธฐ ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ ํ๋ ์์ํฌ ์ ๋๋ก ์ ์ํ ์ ์๊ฒ ๋ค์!
๊ฐ์
Combine ํ๋ ์์ํฌ๋ ์๊ฐ์ ๋ฐ๋ฅธ ๊ฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ ์ธ์ Swift API๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด ๊ฐ๋ค์ ์ฌ๋ฌ ์ข ๋ฅ์ ๋น๋๊ธฐ ์ด๋ฒคํธ๋ฅผ ๋ํ๋ผ ์ ์์ต๋๋ค.
Combine์ ์๊ฐ์ ๋ฐ๋ผ ๋ณ๊ฒฝ๋ ์ ์๋ ๊ฐ์ ๋ฐฉ์ถํ๋ publisher์ publisher๋ก๋ถํฐ ๊ฐ๋ค์ ์ ๋ฌ๋ฐ๋ subscriber๋ฅผ ์ ์ธํฉ๋๋ค.
Publisher ํ๋กํ ์ฝ์ ์ผ๋ จ์ ๊ฐ์ ์๊ฐ์ ๋ฐ๋ผ ์ ๋ฌํ ์ ์๋ ํ์ ์ ์ ์ธํฉ๋๋ค.
Publisher๋ upstream publisher๋ก๋ถํฐ ๋ฐ์ ๊ฐ์ ๋ํด ํ๋ํ๊ณ ์ด ๊ฐ๋ค์ republishํ๋ ์ฐ์ฐ์๋ค์ ๊ฐ์ง๋๋ค.
Subscriber๋ publisher ์ฒด์ธ์ ๋์์ ๊ฐ๋ค์ ์์ ๋ฐ์ ๋ ๋์๋ฉ๋๋ค.
subscriber๋ค์ด ๋ช ์์ ์ผ๋ก ๊ฐ์ ์์ฒญํ ๋๋ง publisher๋ค์ ๊ฐ์ ๋ฐฉ์ถํฉ๋๋ค.
์ด๋ฅผ ํตํด ์ฐ๋ฆฌ๊ฐ ๋ง๋๋ subscribers ์ฝ๋๋ ์ฐ๊ฒฐ๋ publisher๋ค๋ก๋ถํฐ ์ผ๋ง๋ ๋นจ๋ฆฌ ์ด๋ฒคํธ๋ฅผ ๋ฐ๋์ง ํต์ ํ ์ ์์ต๋๋ค.
Timer, NotificationCenter ๋ฐ URLsession์ ํฌํจํ ์ฌ๋ฌ Foundation ์ ํ์ publisher๋ฅผ ํตํด ๊ธฐ๋ฅ์ ๋ ธ์ถํฉ๋๋ค.
๋ํ, Combine์ Key-Value Observing์ ์ค์ํ๋ ๋ชจ๋ ์์ฑ์ ๋ํ ๋ด์ฅ๋ publisher๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ฌ๋ฌ publisher์ output์ ๊ฒฐํฉํ์ฌ ์ํธ ์์ฉ์ ์กฐ์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด text field์ publisher๋ฅผ ๊ตฌ๋ ํ๊ณ ํ ์คํธ ๊ฐ์ ๋ณํ์ ๋ฐ๋ฅธ URL ์์ฒญ์ ์ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ค๋ฅธ publisher๋ฅผ ์ฌ์ฉํ์ฌ ์๋ต์ ์ฒ๋ฆฌํ๊ณ ์ฑ์ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค.
Combine์ ์ฑํํ๋ฉด ์ด๋ฒคํธ ์ฒ๋ฆฌ ์ฝ๋๋ฅผ ์ค์ ์ง์คํํ๊ณ ์ค์ฒฉ ํด๋ก์ ๋ ๋ค๋ฅธ ํ์ ๋ค์ ๊ฐ์ง ์ฝ๋ฐฑ๊ณผ ๊ฐ์ ๋ฌธ์ ๋ฅผ ์ ๊ฑฐํจ์ผ๋ก์จ ์ฝ๋๋ฅผ ์ฝ๊ณ ์ ์งํ๊ธฐ๊ฐ ์ฌ์์ง ๊ฒ์ ๋๋ค.
์ฌ๊ธฐ๊น์ง ๊ณต์๋ฌธ์ ์ค๋ช ์ ๋ฒ์ญํ๋ฉฐ Combine์ด ๋ฌด์์ธ์ง ์์๋ณด์์ต๋๋ค.
Combine์ ํต์ฌ์ด ๋๋ Publisher์ Subscriber์ ๋ํด ์์๋ด ์๋ค!
Publisher
์๊ฐ์ด ํ๋ฆ์ ๋ฐ๋ผ ์ผ๋ จ์ ๊ฐ๋ค์ ์ ์ก(๋ฐฉ์ถ)ํ ์ ์๋ ํ์ ์ ์ ์ธํ๋ ํ๋กํ ์ฝ
protocol Publisher<Output, Failure>
ํ๋์ publisher๋ ํ๋ ํน์ ์ฌ๋ฌ subscriber ์ธ์คํด์ค์๊ฒ ์์๋ค์ ์ ๋ฌํฉ๋๋ค.
subscriber์ Input๊ณผ Failure (associated type)๋ ๊ฐ๊ฐ publisher์ Output ๊ณผ Failure ์ ๋งค์น๊ฐ ๋ฉ๋๋ค.
publisher๋ subscriber๋ฅผ ๋ฐ๊ธฐ ์ํด receive(subscriber:) ๋ฉ์๋๋ฅผ ๊ตฌํํฉ๋๋ค.
๐ receive(subscriber:)
ํน์ ํ subscriber๋ฅผ ํด๋น publisher์ ์ฐ๊ฒฐํฉ๋๋ค.
func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input
subscriber ํ๋ผ๋ฏธํฐ์ ๊ตฌ๋ ์๊ฐ ์ฐ๊ฒฐ๋๊ณ , ๊ฐ์ ๋ฐ์ ์ ์๊ฒ ๋ฉ๋๋ค.
Publisher์ ๊ตฌํ๋ฅผ ์ํด์๋ ๋ฐ๋์ ํด๋น ๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด publisher๋ subscriber์์ ๋ค์๊ณผ ๊ฐ์ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
- receive(subscription:): ๊ตฌ๋ ์์๊ฒ ๊ตฌ๋ ์ด ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด์ก๊ณ ์์ดํ ๋ค์ ์์ฒญํ ์ ์์์ ์๋ ค์ฃผ๋ ๋ฉ์๋. ๊ตฌ๋ ์์ฒญ์ ์น์ธํ๊ณ Subscription ์ ๋ฐํํจ. ๊ตฌ๋ ์๋ subscription์ ์ด์ฉํด publisher์๊ฒ element๋ฅผ ์๊ตฌํ๊ณ ์ด๋ฅผ ์ด์ฉํด publishing ์ ์ทจ์ํ ์ ์๋ค.
- receive(_:): ํ๋์ ์์๋ฅผ ๊ตฌ๋ ์์๊ฒ ์ ๋ฌํ๋ค.
- receive(completion:): publishing์ด ์ ์์ ์ผ๋ก ๋๋ ์ค๋ฅ๋ก ์ข ๋ฃ๋์์์ ๊ตฌ๋ ์์๊ฒ ์๋ฆฐ๋ค.
downstream ๊ตฌ๋ ์(subscriber)๋ค์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ ค๋ฉด ๋ชจ๋ publisher๊ฐ ํด๋น ํ๋กํ ์ฝ(=Publisher)์ ์ค์ํด์ผ ํฉ๋๋ค.
Publisher์ ๋ํ extentension์ ์ ๊ตํ ์ด๋ฒคํธ ์ฒ๋ฆฌ ์ฒด์ธ์ ์์ฑํ๊ธฐ ์ํด ๊ตฌ์ฑํ๋ ๋ค์ํ ์ฐ์ฐ์๋ฅผ ์ ์ํฉ๋๋ค.
๊ฐ ์ฐ์ฐ์๋ Publisher ํ๋กํ ์ฝ์ ๊ตฌํํ๋ ํ์ ์ ๋ฐํํฉ๋๋ค.
์ด๋ฌํ ํ์ ๋ค ๋๋ถ๋ถ์ Publishers ์ด๊ฑฐํ์ ๋ํ ํ์ฅ์ผ๋ก ์กด์ฌํฉ๋๋ค.
Subscriber
publisher ๋ก๋ถํฐ ์ ๋ ฅ์ ๋ฐ์ ์ ์๋ ํ์ ์ ์ ์ธํ๋ ํ๋กํ ์ฝ
protocol Subscriber<Input, Failure> : CustomCombineIdentifierConvertible
Subscriber ์ธ์คํด์ค๋ Publisher๋ก๋ถํฐ ๋ ์ฌ์ด์ ๊ด๊ณ์ ๋ํ ๋ณ๊ฒฝ์ ์ค๋ช ํ๋ life cycle ์ด๋ฒคํธ์ ํจ๊ป ๊ฐ์ ์คํธ๋ฆผ์ ๋ฐ์ต๋๋ค.
subscriber์ Input๊ณผ Failure associated type์ ์ฐ๊ฒฐ๋ publisher์ Output๊ณผ Failure ์ ์ผ์นํด์ผ ํฉ๋๋ค.
publisher์ subscribe(_:) ๋ฉ์๋๋ฅผ ํธ์ถํจ์ผ๋ก์จ subscriber๋ฅผ publisher์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถ ํ์๋ publisher๊ฐ subscriber์ receive(subscription:) ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
์ด๋ subscriber์๊ฒ ๊ฐ์ ์์ฒญํ๊ณ ์ ํ์ ์ผ๋ก ๊ตฌ๋ ์ ์ทจ์ํ๋๋ฐ ์ฌ์ฉ๋๋ Subscription ์ธ์คํด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
subsriber๊ฐ ์ต์ด์ ์์ฒญ์ ํ ํ์๋ ์๋กญ๊ฒ ๊ฒ์๋๋ ์์๋ค์ ์ ๋ฌํ๊ธฐ ์ํด publisher๋ ๋น๋๊ธฐ์ ์ผ๋ก receive(_:)๋ฅผ ํธ์ถํฉ๋๋ค.
publisher๊ฐ publishing์ ์ค๋จํ๊ฒ ๋๋ฉด, subscriber๋ Subsribers ํ์ ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ฌ receive(completion:)์ ํธ์ถํฉ๋๋ค. Completion์ publishing์ด ์ ์์ ์ผ๋ก ์๋ฃ๋๋์ง ํน์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ ๋๋ค.
Publisher ํ์ ์ ๋ํ ์ฐ์ฐ์๋ก ์๋์ subsriber๋ฅผ ์ ๊ณตํฉ๋๋ค.
- sink(receiveComplete:receiveValue:): ์๋ฃ ์ ํธ์ ์ ์์๋ฅผ ์์ ํ ๋๋ง๋ค ์์์ ํด๋ก์ ๋ฅผ ์คํํฉ๋๋ค.
- assign(to:on :): ์๋ก ๋ฐ์ ๊ฐ์ keyPath์ ๋ฐ๋ผ ์ฃผ์ด์ง ์ธ์คํด์ค์ property์ ํ ๋นํฉ๋๋ค.
์ฌ๊ธฐ๊น์ง Combine์ ๊ธฐ๋ณธ์ ์ธ ๋ด์ฉ์ ๋ํด ์ ๋ฆฌํด๋ณด์๋๋ฐ์!
ํ๋ก์ ํธ ๊ฐ๋ฐ์ ํตํด ์ ์ฉํ๊ฒ ๋๋ ๋ด์ฉ๋ค๋ ์ ๋ฆฌํ๋ฉด์ ๊ตฌ์ฒด์ ์ธ ์ฌ์ฉ๋ฐฉ๋ฒ, ์์์ ๋ํด์๋ ๊ฐ์ ธ์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค~!!
[์ฐธ๊ณ ์๋ฃ]
https://developer.apple.com/documentation/combine
https://ios-development.tistory.com/1113
'๐ iOS > Combine' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Combine] ๊ด์ฐฐ๊ฐ๋ฅํ ๋ฐ์ดํฐ ๋ง๋ค๊ธฐ - ObservableObject์ @Published (2) | 2024.08.22 |
---|---|
[Combine] WWDC19 - Introducing Combine (0) | 2024.04.15 |