| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 |
- FilteringOperator
- compactMap
- replaceNil
- RxSwift
- autoLayout
- Publisher
- 비동기
- Cocoapods
- hugging
- priority
- RxSwift비교
- 코딩에이전트
- switchToLatest
- ios
- Combine
- Combine개념
- Swift
- CombineOperator
- PassthroughSubject
- removeDuplicates
- CurrentValueSubject
- AI개발도구추천
- ChatGPTCodex
- 라이브러리
- Codex리뷰
- tryMap
- Codex사용법
- SwiftCombine
- RxSwift에서Combine
- CURSOR
- Today
- Total
Tong's Blog
[Swift] Combine Publisher 종류 정리 + RxSwift와 비교해보기 (2편) 본문
안녕하세요.
지난 글에서는 Combine의 기본 개념과 Publisher / Subscriber, 그리고 RxSwift와의 대응 관계를 간단히 살펴보았는데요.
이번 글에서는 Combine에서 자주 사용하는 Publisher 종류와, 이에 대응되는 RxSwift 컴포넌트를 함께 비교하면서 정리해보려고 합니다.
실제로 개발을 하다 보면 "어떤 Publisher를 써야 하지?", "RxSwift에서 쓰던 그 기능은 Combine에서는 뭐지?" 이런 고민이 자연스럽게 생기기 때문에 이번 내용이 앞으로의 글을 이해하는 데도 큰 도움이 될 것 같아요.
Publisher란 무엇인가?
Combine에서 Publisher는 값을 만들어 내는 생산자입니다.
하지만 모든 Publisher가 동일한 방식으로 값을 내보내는 건 아니고, 상황에 따라 다양한 타입이 존재합니다.
대표적으로 아래 세 가지 유형이 있습니다.
- 한 번만 값을 내보내는 Publisher
- 비동기 작업의 성공/실패를 표현하는 Publisher
- 시간이나 이벤트 흐름에 따라 지속적으로 값을 내보내는 Publisher
이제 각각을 예시와 함께 살펴보고, RxSwift에서는 무엇과 대응되는지도 같이 보겠습니다.
1. Just – 값을 단 한 번만 방출하고 끝나는 Publisher
Combine에서 가장 기본적인 Publisher 입니다.
https://developer.apple.com/documentation/combine/just
Just | Apple Developer Documentation
A publisher that emits an output to each subscriber just once, and then finishes.
developer.apple.com
func testJust() {
let publisher = Just("Hello, Combine")
var bag = Set<AnyCancellable>()
publisher
.sink { value in
print("값:", value)
}
.store(in: &bag)
}
// 값: Hello, Combine
특징
- 반드시 하나의 값만 방출
- 즉시 완료됨
- 에러 타입이 Never
RxSwift 대응
- Observable.just("Hello")
둘의 역할은 거의 동일합니다.
2. Empty – 아무 값도 방출하지 않고 즉시 완료되는 Publisher
Empty는 이름 그대로 값을 방출하지 않고, finished completion만 내보내는 Publisher입니다.
Combine의 체인을 구성할 때 “아무것도 하지 않고 정상적으로 끝낸다”라는 의도를 표현할 때 유용합니다.
https://developer.apple.com/documentation/combine/empty
Empty | Apple Developer Documentation
A publisher that never publishes any values, and optionally finishes immediately.
developer.apple.com
let emptyPublisher = Empty<String, Never>()
var bag = Set<AnyCancellable>()
emptyPublisher
.sink(
receiveCompletion: { print("완료:", $0) },
receiveValue: { value in
print("값:", value)
}
)
.store(in: &bag)
// 완료: finished
특징
- 어떤 값도 방출하지 않음 (receiveValue는 호출되지 않음)
- 즉시 .finished completion 전송
- Never 에러 타입이 기본
- fallback / default 흐름을 만들 때 자주 사용
RxSwift 대응
- Observable<String>.empty()
값 없이 완료만 발생하는 Observable
3. Future – 비동기 작업의 결과(성공/실패)를 단 한 번 방출
Future는 비동기 로직을 한 번 실행하고 성공(.success) 또는 실패(.failure) 값을 단 한 번 전달합니다.
https://developer.apple.com/documentation/combine/future
Future | Apple Developer Documentation
A publisher that eventually produces a single value and then finishes or fails.
developer.apple.com
예시로 간단한 네트워크 시뮬레이션을 해보면:
func loadData() -> Future<String, Error> {
return Future { promise in
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
let success = Bool.random()
if success {
promise(.success("성공 결과"))
} else {
promise(.failure(NSError(domain: "", code: -1)))
}
}
}
}
// 사용
var bag = Set<AnyCancellable>()
loadData()
.sink(
receiveCompletion: { print("완료: \($0)") },
receiveValue: { print("값:", $0) }
)
.store(in: &bag)
// 성공하면
// 값: 성공 결과
// 완료: finished
// 실패하면
// 완료: failure(Error Domain= Code=-1 "(null)")
RxSwift 대응
- Single<T>
- 성공/실패를 한 번만 전달한다는 점에서 동일합니다.
4. Deferred – 구독 시점에 Publisher 생성
Publisher 체인을 만들 때 "미뤄둔 생성"이 필요할 때 사용합니다.
https://developer.apple.com/documentation/combine/deferred
Deferred | Apple Developer Documentation
A publisher that awaits subscription before running the supplied closure to create a publisher for the new subscriber.
developer.apple.com
let deferredPublisher = Deferred {
Just(Int.random(in: 1...100))
}
// 이후 사용할때마다 Int 값이 생성되서 사용
사용할 때마다 새로운 난수를 내보냅니다.
RxSwift 대응
- Observable.deferred { ... }
5. PassthroughSubject – 이벤트를 그대로 흘려보내는 Subject
Subject는 Publisher + Subscriber 역할을 동시에 수행하는 조금 특별한 타입입니다.
https://developer.apple.com/documentation/combine/passthroughsubject
PassthroughSubject | Apple Developer Documentation
A subject that broadcasts elements to downstream subscribers.
developer.apple.com
let subject = PassthroughSubject<String, Never>()
var bag = Set<AnyCancellable>()
subject
.sink { value in
print("값:", value)
}
.store(in: &bag)
subject.send("첫 번째")
subject.send("두 번째")
// 값: 첫 번째
// 값: 두 번째
특징
- 초기값이 없음
- 구독 이후 발생하는 값만 전달
RxSwift 대응
- PublishSubject
6. CurrentValueSubject – 최신 값 1개를 항상 들고 있는 Subject
PassthroughSubject 와 달리 초기값을 필수로 가지고 시작합니다.
https://developer.apple.com/documentation/combine/currentvaluesubject
CurrentValueSubject | Apple Developer Documentation
A subject that wraps a single value and publishes a new element whenever the value changes.
developer.apple.com
let count = CurrentValueSubject<Int, Never>(0)
count
.sink { value in
print("값:", value)
}
.store(in: &bag)
count.send(1)
count.send(2)
print("현재 값:", count.value)
// 값: 0
// 값: 1
// 값: 2
// 현재 값: 2
특징
- 최신 값 보관
- 새로운 구독자에게 즉시 최신 값을 전달
RxSwift 대응
- BehaviorSubject
- 실무에서는 BehaviorRelay에 가장 많이 대응
7. Timer.TimerPublisher – 일정 시간마다 값을 반복적으로 방출
Combine에는 시간 기반 Publisher가 기본 제공됩니다.
let timer = Timer.publish(every: 1, on: .main, in: .default)
var bag = Set<AnyCancellable>()
timer
.autoconnect()
.sink { value in
print("타이머:", value)
}
.store(in: &bag)
// 타이머: 2025-11-20 10:56:02 +0000
// 타이머: 2025-11-20 10:56:03 +0000
// 타이머: 2025-11-20 10:56:04 +0000
// 타이머: 2025-11-20 10:56:05 +0000
// ...
RxSwift 대응
- Observable<Int>.interval
- Observable<Int>.timer
Publisher 매핑표 업데이트
| Combine Publisher | 특징 | RxSwift 대응 |
| Just | 단일 값 즉시 방출 | Observable.just |
| Future | 비동기 결과 1회 | Single |
| Deferred | 구독 시점 생성 | Observable.deferred |
| Empty | 값 없이 완료 | Observable.empty / never |
| PassthroughSubject | 이벤트 스트림 | PublishSubject |
| CurrentValueSubject | 최신 값 보관 | BehaviorSubject / BehaviorRelay |
| TimerPublisher | 주기적 시간 이벤트 | Observable.interval / timer |
마무리하며
이번 글에서는 Combine에서 제공하는 주요 Publisher 타입들을 정리해보고, RxSwift의 대응되는 컴포넌트와 비교해보았습니다.
다음 글에서는 이 Publisher들을 어떻게 조합하고 변환하는지, 즉 Operator 비교(map, flatMap, debounce, throttle, combineLatest 등) 를 다뤄보는 내용을 이어서 작성해보려고 합니다.
읽어주셔서 감사합니다!
'iOS > Combine' 카테고리의 다른 글
| [Swift] Combine 조합 Operator 정리 + RxSwift 비교해보기 (0) | 2026.02.19 |
|---|---|
| [Swift] Combine Filtering Operator 정리 + RxSwift 비교해보기 (0) | 2026.01.27 |
| [Swift] Combine Transforming Operator 정리 [map, tryMap, compactMap, flatMap, scan, replaceNil] + RxSwift 비교 (0) | 2026.01.06 |
| [Swift] Combine 개념과 RxSwift 와 비교해보기 (0) | 2025.11.12 |