Swift
NSNotificationCenter
addObserver
iOS Development
Swift Programming

NSNotificationCenter addObserver in Swift

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Overview of NSNotificationCenter in Swift

NSNotificationCenter is a crucial part of Apple's framework for messaging and notifications in iOS and macOS applications. It allows different parts of an application to communicate with each other by sending and receiving notifications. Notifications are one-to-many communication mechanisms that facilitate decoupled interactions.

AddObserver Method

The addObserver method is the heart of the observer pattern in NSNotificationCenter. It allows objects to listen for specific notifications posted by other parts of the application.

Basic Usage

To create a notification observer, you use the addObserver method. Here is a simple example:

swift
1import Foundation
2
3class NotificationObserver {
4    init() {
5        NotificationCenter.default.addObserver(
6            self, 
7            selector: #selector(self.handleNotification(_:)), 
8            name: .someNotification, 
9            object: nil
10        )
11    }
12
13    @objc func handleNotification(_ notification: Notification) {
14        print("Notification received: \(notification.name.rawValue)")
15    }
16}
17
18// Post the notification
19NotificationCenter.default.post(name: .someNotification, object: nil)

Explanation of Parameters

  • Observer: The object registering as an observer. Typically, this is self.
  • Selector: The method to be called when the notification is received. This method should take a single parameter, which is an instance of Notification.
  • Name: The name of the notification the observer wants to receive. It's usually a static constant or a computed property of type NSNotification.Name.
  • Object: The sender of the notification that the observer is interested in. Passing nil means the observer wants to receive the specified notification from any object.

Use Cases and Examples

Decoupled Components

Imagine you have a view controller that needs to update its UI when some data changes in the model layer. By using NSNotificationCenter, the model can post a notification when the data changes, and the view controller can update itself without direct reference to the model.

swift
1class Model {
2    var data: String = "" {
3        didSet {
4            NotificationCenter.default.post(name: .dataDidChange, object: nil)
5        }
6    }
7}
8
9class ViewController {
10    init() {
11        NotificationCenter.default.addObserver(
12            self, 
13            selector: #selector(updateUI), 
14            name: .dataDidChange, 
15            object: nil
16        )
17    }
18
19    @objc func updateUI() {
20        print("UI needs to update due to data change.")
21    }
22}

Handling Application Events

Another scenario might be responding to system-level notifications, such as keyboard appearance.

swift
1NotificationCenter.default.addObserver(
2    self,
3    selector: #selector(keyboardWillShow),
4    name: UIResponder.keyboardWillShowNotification,
5    object: nil
6)
7
8@objc func keyboardWillShow(notification: Notification) {
9    // Adjust UI for keyboard
10    print("Keyboard will show.")
11}

Best Practices

Removing Observers

Always remove observers when they are no longer needed or before the observer is deallocated, to avoid memory leaks or crashes due to dangling pointers.

swift
NotificationCenter.default.removeObserver(self)

With the introduction of Swift and ARC (Automatic Reference Counting), not removing observers is less of an issue since Swift 4. However, it's still a good practice for clarity and ensuring that old versions of Swift or Objective-C code behave safely.

Utilizing Blocks

For increased flexibility, especially with Swift's closure capabilities, consider using addObserver(forName:object:queue:using:):

swift
1NotificationCenter.default.addObserver(
2    forName: .someNotification,
3    object: nil, 
4    queue: .main
5) { notification in
6    print("Closure received notification: \(notification.name.rawValue)")
7}

Summary Table

Key PointDescription
What is it?An observer pattern implementation to handle notifications.
Basic MethodaddObserver(_:selector:name:object:)
SelectorThe method invoked when a notification is caught.
Notification NameNSNotification.Name for identifying notification types.
ObjectThe origin of the posted notification. Use nil to accept any origin.
RemovalUse removeObserver(self) to prevent unwanted behavior.
Block-based APIUse addObserver(forName:object:queue:using:) for closure-based handling.

By understanding how to effectively use NSNotificationCenter and its addObserver method, developers can create flexible, highly-decoupled systems where components can communicate seamlessly. This article provides a groundwork for implementing such observer patterns in Swift applications.


Course illustration
Course illustration

All Rights Reserved.