Software Design

Swift Observer Pattern: From NotificationCenter to Combine

When building an iOS app, you inevitably hit situations like this: something changes on screen A, and a distant screen B also needs to update.

3 min read
Cover image for Swift Observer Pattern: From NotificationCenter to Combine

When building an iOS app, you inevitably hit situations like this: something changes on screen A, and a distant screen B also needs to update.

Force-connect screens with delegates, and the code can quickly become tangled like spaghetti.

That’s where the Observer pattern comes in. In Swift, the most natural progression is to start with NotificationCenter and move to Combine.

This article covers what the Observer pattern is, how to use NotificationCenter, and the widely used Combine, with practical code examples.

What is the Observer pattern?

The Observer pattern is a structure that automatically notifies objects watching a subject when its state changes.

Think of YouTube subscriptions. When a channel (publisher) uploads a video, subscribers (observers) receive a notification.

The key point is that the publisher and observers do not need to know each other directly.

Publisher and observers exchange notifications without knowing each other
Publisher and observers exchange notifications without knowing each other

The channel does not care how many subscribers there are or who they are. It just announces, “A video is up.”

This loose coupling keeps code from getting tangled and makes later changes much easier.


How do you use NotificationCenter?

NotificationCenter is Apple’s built-in tool for the Observer pattern. You can use it immediately without an additional library.

First, define the notification name and write the publishing-side code.

// Define notification name
extension Notification.Name {
    static let didLogin = Notification.Name("didLogin")
}

// Publish notification when login succeeds
NotificationCenter.default.post(name: .didLogin, object: nil)

On the receiving side, register an observer like this.

// Subscribe to notification
NotificationCenter.default.addObserver(
    self, selector: #selector(handleLogin),
    name: .didLogin, object: nil
)

One thing to watch out for: the old approach (addObserver + selector) can cause problems if you do not call removeObserver when a screen disappears.

Since iOS 9, much of this cleanup happens automatically, but with block-based APIs, you still need to manage the returned token.


What do you gain by moving to Combine?

Combine is a reactive programming framework Apple introduced in 2019. It is available from iOS 13 onward.

NotificationCenter can also be converted into a Combine Publisher, so it integrates naturally with existing code.

// NotificationCenterto the  Combine approach
let token = NotificationCenter.default
    .publisher(for: .didLogin)
    .sink { _ in
        print("Detect login!")
    }

Combine’s real strength is that you can chain data flows together.

You can transform values with operators such as map and filter, and combine multiple events.

If you store the subscription returned by sink (AnyCancellable) in a variable, the subscription is automatically canceled when that variable disappears. Memory management becomes much easier.

I got the hang of it by keeping the code open and writing it out by hand
I got the hang of it by keeping the code open and writing it out by hand

So which one should you use?

It depends on the situation. Here is a summary table.

Item NotificationCenter Combine
Introduced Older built-in API iOS 13+
Learning curve Low Medium or higher
Value transformation Difficult Flexible with map/filter
Memory management Handle manually Automatic when subscription is stored

For one or two simple notifications, NotificationCenter is enough.

If the data flow is complex or you need to combine multiple events, Combine is much cleaner.

If you are just starting, learn the concept with NotificationCenter and move to Combine when you are comfortable.

Of course, SwiftUI and async/await are dominant today, so consider them as well for new projects.

It feels so satisfying when one notification updates another screen too
It feels so satisfying when one notification updates another screen too

Summary

Today we explored the Swift Observer pattern, from NotificationCenter to Combine.

Do not try to understand everything perfectly from the start. Begin by creating one small notification yourself. Writing it by hand makes the idea click much faster. You’ve got this!

Continue reading