Combine
Combine is Apple's reactive framework for asynchronous values that arrive over time: taps, network responses, property changes. Instead of callbacks and delegates you describe a stream of values and subscribe to it. The core idea is a split of roles: one side emits values, the other requests them, and the link between them controls demand and lifecycle.
The beginner traps hide in exactly those roles. A publisher does not "push" values on its own — it waits for demand from a subscriber. A subscriber is not the same thing as the subscription that connects the pair and lives only while you hold an AnyCancellable. And CurrentValueSubject and @Published add stored state on top of the stream, which is usually what you bind to the UI in MVVM. The full map is in the layers below.
Topic map
- Publisher — the source of a stream of values plus a completion or failure event, lazy until demand appears.
- Subscriber — the side that requests and receives values;
sinkandassignas ready-made subscribers. - AnyCancellable — the subscription token whose retention keeps it alive and whose release cancels it.
- CurrentValueSubject — a publisher that also stores the current value and replays it to new subscribers.
- The @Published property — a property wrapper that turns a plain property into a publisher reachable via the
$prefix.
Common traps
| Mistake | Consequence |
|---|---|
| Thinking a publisher emits values eagerly regardless of demand | Wrong model — with no subscriber and no demand the stream does not flow |
| Confusing the subscriber with the subscription object | Missing which one controls demand and lifecycle |
Not retaining AnyCancellable | The subscription is cancelled immediately and the screen stops updating |
Confusing CurrentValueSubject with PassthroughSubject | Expecting a replayed current value where there is none |
Forgetting the $ prefix on a @Published property | Reaching the value instead of its publisher, so no subscription is made |
| Treating any publisher as a one-shot callback | Losing that it is a stream of many values plus completion |
Interview relevance
Combine is asked to check whether you separate the source, the sink, and the link between them, not just whether you can write .sink. A candidate who explains the stream as "a publisher emits values on the subscriber's demand, and the subscription manages that demand and lives as long as the cancellable is held" immediately gets ahead of someone who calls all of it "subscriptions".
Typical checks:
- The difference between a publisher, a subscriber, and a subscription, and which one manages what.
- Why
AnyCancellablemust be stored, and exactly where in a view model. - How
CurrentValueSubjectdiffers fromPassthroughSubjectand from@Published. - How to bind a view model's state to a controller or a SwiftUI view.
Common wrong answer: "a publisher is a variable that holds a value and a subscriber reads it synchronously". In fact a publisher is a stream over time, values flow only on the subscriber's demand, and without a retained cancellable the subscription is cancelled at once.