Publishers, operators and subscribers

Combine Junior Swift 5.1+ iOS 13+ Reviewed By Alok Singh

Order the steps

Put these steps of a Combine pipeline in order.

  • Start from a publisher, such as $query or NotificationCenter.default.publisher(for:)
  • Apply operators, such as map, filter and debounce
  • Store the AnyCancellable so the subscription stays alive
  • Subscribe with sink or assign
Hint 1 of 1

Nothing runs until there is a subscriber.

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A B D C

  1. Start from a publisher, such as $query or NotificationCenter.default.publisher(for:) Every pipeline begins with a source of values.
  2. Apply operators, such as map, filter and debounce Each operator wraps the upstream and returns a new publisher.
  3. Subscribe with sink or assign Subscribing creates the subscription and starts the flow.
  4. Store the AnyCancellable so the subscription stays alive Dropping it cancels the subscription.

30-second answer

A Publisher declares an Output and a Failure type and delivers values and then optionally one completion (finished or failure). Operators are methods that return new publishers, such as map, filter and debounce. Subscribers like sink and assign request values and receive them. Subscribing returns an AnyCancellable that keeps the subscription alive.

Practise saying it · 30 s. No recording, just a timer

Explain Combine's building blocks.

Say your answer out loud, then check which of these points you covered:

  • Publisher with Output/Failure
  • Operators return publishers
  • Subscribers and cancellables

Deep dive

Failure == Never means the publisher can't fail.

After a completion, a publisher sends no more values.

assign(to: &$property) ties the subscription's lifetime to the @Published property, without a cancellable.

Schedulers decide where values are delivered: receive(on:).

Keyboard height pipeline Type-checked · Swift 6.4
NotificationCenter.default
    .publisher(for: UIResponder.keyboardWillShowNotification)
    .compactMap { ($0.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height }
    .receive(on: RunLoop.main)
    .sink { [weak self] height in self?.bottomInset = height }
    .store(in: &cancellables)

Common mistakes

  • Expecting values after a completion.
  • Assuming operators run eagerly.

Senior take & follow-ups

Seniors describe the contract: values, then at most one completion, with types for both.

Follow-up questions

Think of your answer first, then open the hint.

  1. What does assign(to: &$x) need?

    Show hint

    A @Published property; no cancellable is returned.

  2. subscribe(on:) vs receive(on:)?

    Show hint

    Where the upstream work starts versus where values arrive.

Suggest a fix if something here is wrong or out of date.