Introduction to Combine
Combine is Apple's framework for working with values that arrive over time . In this lesson you'll meet publishers, subscribers, @Published , sink , and AnyCancellable — and learn when Combine beats plain async/await.
Learn Introduction to Combine in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
- • What a Publisher and Subscriber are, and how data flows between them
- • Use @Published to turn a property into a stream of changes
- • Attach a subscriber with sink
- • Keep subscriptions alive with AnyCancellable and store(in:)
- • Read a publisher's Output and Failure types
- • Decide when to reach for Combine vs async/await
📊 Combine Building Blocks
Piece
Role
Example
Publisher
Emits values over time
Just(5)
Subscriber
Receives values
.sink { … }
@Published
Property to publisher
@Published var n = 0
AnyCancellable
Holds a subscription
.store(in: &bag)
1️⃣ Publishers and Subscribers
A publisher produces a stream of values; a subscriber consumes them. The simplest subscriber is sink , which runs a closure for each value. Many everyday types become publishers — even arrays.
2️⃣ @Published — Properties as Streams
Inside an ObservableObject , marking a property with @Published creates a publisher you reach with the $ prefix. Every change is broadcast to subscribers — this is exactly how SwiftUI views stay in sync.
Your turn. Fill in the two blanks to turn an array into a publisher and subscribe to it.
3️⃣ AnyCancellable — Keeping It Alive
A subscription stays active only as long as you hold its AnyCancellable . The common pattern is a Set<AnyCancellable> property plus .store(in:) , so every subscription lives as long as the owning object.
Now you try. Fill in the collection type and the storing operator.
Pro Tips
- 💡 Always store your cancellables. A forgotten subscription is silently cancelled the moment its token goes out of scope.
- 💡 Use Never as Failure when a stream can't error — it lets you use the simpler single-closure sink .
- 💡 Combine vs async/await: one-shot call → async/await; ongoing stream → Combine.
- 💡 Think in streams. Ask "what values flow over time?" before writing pipelines.
Common Errors (and the fix)
- Subscriber never fires — you didn't keep the AnyCancellable . Store it with .store(in:&bag) .
- "Cannot convert value of type 'Published<Int>.Publisher'" — subscribe to the $ projected value, e.g. object.$count , not the raw property.
- Compiler can't find Combine types — add import Combine at the top of the file.
- Error-handling closure required — your publisher's Failure isn't Never ; use the two-closure sink(receiveCompletion:receiveValue:) .
📋 Quick Reference
Task
Code
Meaning
One-value publisher
emit 5, finish
Array publisher
[1,2].publisher
emit each
Published property
stream of changes
Subscribe
.sink { v in … }
closure subscriber
Retain
keep alive
Frequently Asked Questions
Mini-Challenge: Score Tracker
Build a small ObservableObject and subscribe to its published property. Run it and check your output against the comments.
🎉 Lesson Complete!
- ✅ Publishers emit values over time; subscribers receive them
- ✅ @Published turns a property into a stream of changes
- ✅ sink attaches a closure-based subscriber
- ✅ Hold the AnyCancellable (often in a Set ) to keep it alive
- ✅ Use Combine for ongoing streams; async/await for one-shot work
- ✅ Next lesson: Combine Operators & Pipelines — transform streams with map, filter, debounce and more
Practice quiz
What does a Combine Publisher represent?
- A one-time function call
- A source that emits values over time
- A UI view
- A database table
Answer: A source that emits values over time. A Publisher emits a sequence of values (and optionally a completion) over time.
What role does a Subscriber play?
- It emits values
- It receives values from a publisher
- It stores values on disk
- It cancels the app
Answer: It receives values from a publisher. A Subscriber receives and reacts to the values a publisher emits.
Which property wrapper turns a property into a publisher inside an ObservableObject?
- @State
- @Binding
- @Published
- @Environment
Answer: @Published. @Published automatically publishes changes to the wrapped property.
What does the sink operator do?
- Sorts values
- Attaches a closure-based subscriber to receive values
- Filters values
- Deletes the publisher
Answer: Attaches a closure-based subscriber to receive values. sink attaches a subscriber using closures for received values and completion.
Why must you store the result of sink in an AnyCancellable?
- For logging
- It is required by SwiftUI
- To speed up emissions
- To keep the subscription alive; if deallocated it cancels
Answer: To keep the subscription alive; if deallocated it cancels. When the AnyCancellable is deallocated the subscription is cancelled, so you must retain it.
A Publisher's two generic types describe its...
- Output value and Failure error
- Input and View
- Key and Value
- Start and End
Answer: Output value and Failure error. Publisher<Output, Failure> declares the value type and the error type.
Which Failure type means a publisher can never emit an error?
- Error
- Any
- Never
- Void
Answer: Never. A Failure of Never signals the publisher cannot fail.
Just(5) is an example of what?
- An operator
- A publisher that emits one value then completes
- A subscriber
- A cancellable
Answer: A publisher that emits one value then completes. Just emits a single value and then finishes.
Combine is generally a good fit when you need to...
- Run a single async network call
- Compose ongoing streams of events declaratively
- Store data in Core Data
- Render a static view
Answer: Compose ongoing streams of events declaratively. Combine shines for composing continuous streams of events over time.
For a single one-shot asynchronous task, Apple often recommends...
- Combine over async/await
- GCD only
- async/await instead of Combine
- Never using either
Answer: async/await instead of Combine. async/await is usually simpler for one-shot async work; Combine suits ongoing streams.
Continue this course
- Previous: Custom View Modifiers & ViewBuilder
- Next: Combine Operators & Pipelines