NSNotificationCenter addObserver in Swift: Complete Guide with Live Examples
Imagine you're writing a pizza ordering app. The user clicks "Pay" on the cart screen, and a few seconds later another screen — "Order Status" — should automatically show that the pizza is already on its way. How do you connect these two screens without turning the code into spaghetti of closures and delegates? The answer is NSNotificationCenter (or in modern Swift — simply NotificationCenter).
This pattern is one of the most popular in iOS development. On Stack Overflow, the question "NSNotificationCenter addObserver in Swift" gets thousands of views because even experienced developers sometimes get confused about syntax, memory management, and removing observers. Let's figure out once and for all how to properly use notifications in Swift.
What is NotificationCenter and Why Do You Need It?
NotificationCenter is a built-in iOS mechanism that implements the Observer pattern. It allows some objects (posters) to send messages, and others (observers) to subscribe to those messages and react to them. The main advantage is loose coupling: the sender and receiver know nothing about each other.
When is this useful:
- Notifying one screen about an action on another (e.g., cart → order status)
- Reacting to system events (keyboard appeared, app went to background)
- Updating UI after completing a background data download
In older projects (Objective-C), NSNotificationCenter was used; in Swift starting from iOS 9, it's simply called NotificationCenter. In this article, we'll use modern Swift syntax.
How to Subscribe to a Notification: addObserver
The addObserver method is the heart of the system. It registers an object as an observer of a specific notification. There are two main ways: via selector (classic) and via block (closure).
1. addObserver Method with Selector (target-action)
This method came from Objective-C. You specify the observer object, selector (the method that will be called), notification name, and optionally, the sender object.
import UIKit
class OrderStatusViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Subscribe to the payment notification NotificationCenter.default.addObserver( self, selector: #selector(didReceivePaymentNotification(_:)), name: Notification.Name("PaymentDidSucceed"), object: nil ) } @objc func didReceivePaymentNotification(_ notification: Notification) { print("Payment successful! Updating order status.") // Update UI here } // IMPORTANT: don't forget to unsubscribe! deinit { NotificationCenter.default.removeObserver(self) }}What's important here:
- The handler method must be marked with
@objc— this is a requirement of the Objective-C runtime. - The
notificationparameter of typeNotificationcontainsuserInfo— a dictionary with additional data. - If you pass
object: nil, the observer will receive notifications from any sender.
2. addObserver Method with Closure (iOS 9+)
A modern and safer way is to use a block. It doesn't require @objc and allows capturing external variables.
class PaymentManager { private var observer: NSObjectProtocol? func startObservingPayment() { observer = NotificationCenter.default.addObserver( forName: Notification.Name("PaymentDidSucceed"),