Using NotificationCenter in Swift
Learn how to use NotificationCenter and the observer pattern to broadcast information and communicate between different ViewControllers in your Swift application.
Note:
This tutorial explains how to use the NotificationCenter to pass data and trigger actions between view controllers that are not directly connected.
Overview
In Swift, to notify different parts of your application about changes, we use the NotificationCenter and the NSNotification observer pattern. This allows for a "broadcast" style of communication, where one part of your app can post a notification, and any other interested parts can listen for it and react accordingly.
In our example project, after saving data from the DetailsViewController to Core Data, we want the main ViewController to refresh its data and update the UITableView.
Reference:
Step 1: Posting a Notification
First, let's create and post a notification from the DetailsViewController right after the data has been successfully saved. We will name our notification "dataEntered". After posting, we navigate back to the main ViewController.
// In DetailsViewController, inside the save function's do-catch block
do {
try context.save()
print("Successfully saved data.")
// Post a notification to inform other parts of the app
NotificationCenter.default.post(name: NSNotification.Name("dataEntered"), object: nil)
// Go back to the previous screen
self.navigationController?.popViewController(animated: true)
} catch {
print("Failed to save data: \(error)")
}
Step 2: Observing a Notification
Now, let's switch to the main ViewController to listen for this notification.
The best place to start observing is in the viewWillAppear(_:) method. We use this method because we want to set up the listener every time this view is about to appear on the screen.
In viewWillAppear, we add an observer to the NotificationCenter. This observer listens for a specific notification name ("dataEntered") and, when it hears it, calls a specific function (#selector(getData)).
// In ViewController.swift
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Add an observer to listen for our custom notification
NotificationCenter.default.addObserver(self, selector: #selector(getData), name: NSNotification.Name("dataEntered"), object: nil)
}
Step 3: Responding to the Notification
When the observer "hears" the notification, it executes the @objc function we specified in the selector. In this case, it calls getData().
The getData() function contains our logic to fetch the latest data from Core Data and reload the table view, ensuring the UI is always up-to-date.
// In ViewController.swift
@objc func getData() {
// This is the same function we created in the previous tutorial
// to fetch data from Core Data.
// ... code to fetch data and populate your arrays ...
// Reload the table view to display the new data
tableView.reloadData()
}
With this pattern, you can easily inform different parts of your application about events and trigger corresponding actions, keeping your code decoupled and organized.
Note:
NotificationCenter is a powerful tool for communication between distant parts of your app. Remember to remove the observer in viewWillDisappear or deinit if necessary to prevent memory leaks, especially in older versions of iOS. However, since iOS 9, NotificationCenter handles this automatically for you.