Working with Notifications
1. Using NotificationCenter
| Method | Description | Parameters | Return Type |
|---|---|---|---|
| postNotification(_:) | Posts a notification to the default center | notification: Notification |
Void |
| addObserver(forName:object:queue:using:) | Registers an observer for a specific notification | name: NSNotification.Name?, object: Any?, queue: OperationQueue?, using: (Notification) -> Void |
AnyObject |
| removeObserver(_:) | Removes an observer from the notification center | observer: Any |
Void |
Example: Posting a Notification
import Foundation
let notification = Notification(name: .init("MyNotification"), object: nil, userInfo: ["message": "Hello World"])
NotificationCenter.default.post(notification)
Example: Observing a Notification
import Foundation
let observer = NotificationCenter.default.addObserver(
forName: .init("MyNotification"),
object: nil,
queue: nil
) { notification in
if let message = notification.userInfo?["message"] as? String {
print("Received: \(message)")
}
}
// To remove observer later
// NotificationCenter.default.removeObserver(observer)
2. Registering Observers
| Method | Description | Parameters | Return Type |
|---|---|---|---|
| NotificationCenter.default.addObserver | Registers an observer for a notification | observer: Any, selector: Selector, name: NSNotification.Name?, object: Any? |
Void |
| NotificationCenter.default.removeObserver | Removes an observer from the notification center | observer: Any |
Void |
Example: Registering a Notification Observer
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(handleNotification),
name: NSNotification.Name("CustomNotification"),
object: nil
)
}
@objc func handleNotification(_ notification: Notification) {
print("Received notification: \(notification)")
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
Note: Always remove observers in
deinit to prevent memory leaks.3. Posting Notifications
| Property | Value | Description |
|---|---|---|
| title | String |
Title of the notification |
| body | String |
Main content of the notification |
| badge | Int |
Number to display on app icon (if supported) |
| sound | String |
Name of sound file to play (e.g., "default") |
| category | String |
Category for organizing notifications (e.g., "reminder") |
Example: Posting a Local Notification
import UserNotifications
let content = UNMutableNotificationContent()
content.title = "Meeting Reminder"
content.body = "Your meeting starts in 10 minutes."
content.sound = .default
content.badge = 1
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: "meetingReminder", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error posting notification: \(error)")
} else {
print("Notification posted successfully")
}
}
Note: Ensure that your app has requested permission to post notifications using
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) before attempting to post.
4. Removing Observers
| Method | Description | Notes |
|---|---|---|
| NotificationCenter.default.removeObserver(_ observer: Any) | Removes all observations registered for the specified observer | Must be called with the exact observer object used to register it |
| NotificationCenter.default.removeObserver(_ observer: Any, name: NSNotification.Name?, object: Any?) | Removes observations for a specific notification name and object | Allows selective removal of observer registrations |
Example: Removing All Observers
class MyViewController: UIViewController {
private var observer: Any?
override func viewDidLoad() {
super.viewDidLoad()
observer = NotificationCenter.default.addObserver(
forName: .myNotification,
object: nil,
queue: .main
) { _ in
print("Notification received")
}
}
deinit {
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
}
Example: Removing Specific Observer
class MyViewController: UIViewController {
private var observer: Any?
override func viewDidLoad() {
super.viewDidLoad()
observer = NotificationCenter.default.addObserver(
forName: .myNotification,
object: nil,
queue: .main
) { _ in
print("Notification received")
}
}
func stopListening() {
NotificationCenter.default.removeObserver(
observer!,
name: .myNotification,
object: nil
)
}
}
5. Passing Data with Notifications
| Property | Description | Usage |
|---|---|---|
| userInfo | Dictionary containing additional data to pass with the notification | userInfo: ["message": "Hello", "id": 123] |
Example: Posting a Notification with Data
let userInfo = [
"message": "You have a new message",
"id": 456
]
let notification = UNMutableNotificationContent()
notification.title = "New Message"
notification.body = "You have a new message"
notification.userInfo = userInfo
let request = UNNotificationRequest(
identifier: "messageNotification",
content: notification,
trigger: nil
)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error posting notification: \(error)")
}
}
Example: Receiving Notification Data
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
if let message = userInfo["message"] as? String {
print("Received message: \(message)")
}
if let id = userInfo["id"] as? Int {
print("Received ID: \(id)")
}
completionHandler()
}
6. Using Local Notifications
| Property | Value | Description |
|---|---|---|
| UNNotificationRequest | UNNotificationRequest(identifier: String, content: UNNotificationContent, trigger: UNTrigger?) |
Represents a notification request to be delivered. |
| UNNotificationContent | UNNotificationContent(title: String, body: String, subtitle: String?, sound: UNNotificationSound?, categoryIdentifier: String?, threadIdentifier: String?, userInfo: [AnyHashable : Any]?) |
Defines the content of a notification. |
| UNTimeIntervalTrigger | UNTimeIntervalTrigger(timeInterval: TimeInterval, repeats: Bool) |
Schedules a notification to be delivered after a specified time interval. |
Example: Schedule a Local Notification
import UserNotifications
let content = UNNotificationContent(
title: "Reminder",
body: "Don't forget to complete the task.",
sound: .default
)
let trigger = UNTimeIntervalTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: "reminder", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error scheduling notification: \(error)")
} else {
print("Notification scheduled successfully")
}
}
Example: Handle Notification Response
import UserNotifications
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print("User tapped notification with info: \(userInfo)")
completionHandler()
}
Note: Ensure that your app has the necessary permissions to schedule local notifications. You must request permission from the user before scheduling any notification.
7. Scheduling Local Notifications
| Property | Description | Example |
|---|---|---|
| UNMutableNotificationContent | Content for the notification, including title, body, and sound | |
| UNTimeIntervalNotificationTrigger | Trigger based on a time interval from now | let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: false) |
| UNCalendarNotificationTrigger | Trigger based on calendar components (date and time) | |
| UNLocationNotificationTrigger | Trigger when entering or exiting a geographic region | |
Example: Schedule a Local Notification
import UserNotifications
func scheduleNotification() {
let content = UNMutableNotificationContent()
content.title = "Meeting Reminder"
content.body = "Your meeting starts in 5 minutes."
content.sound = .default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 300, repeats: false)
let request = UNNotificationRequest(identifier: "meetingReminder", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error scheduling notification: \(error)")
}
}
}
Note: You must request permission to schedule notifications using
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]).Warning: Notifications scheduled with
UNTimeIntervalNotificationTrigger may not fire precisely on time due to system optimizations.8. Handling Notification Actions
| Action | Description | Code Example |
|---|---|---|
| UNNotificationAction | Defines an action that users can take from a notification. | |
| UNNotificationCategory | Groups related actions together for notifications. | |
Example: Registering Notification Categories
let acceptAction = UNNotificationAction(
identifier: "ACCEPT_ACTION",
title: "Accept",
options: [.foreground]
)
let declineAction = UNNotificationAction(
identifier: "DECLINE_ACTION",
title: "Decline",
options: [.destructive]
)
let meetingCategory = UNNotificationCategory(
identifier: "MEETING_INVITATION",
actions: [acceptAction, declineAction],
intentIdentifiers: [],
options: []
)
let center = UNUserNotificationCenter.current()
center.setNotificationCategories([meetingCategory])
Example: Handling Notification Action Responses
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let actionIdentifier = response.actionIdentifier
switch actionIdentifier {
case "ACCEPT_ACTION":
print("Meeting accepted")
case "DECLINE_ACTION":
print("Meeting declined")
default:
break
}
completionHandler()
}
Note: Ensure that your app's notification handling logic is robust and handles all possible action identifiers to prevent unexpected behavior.
9. Requesting Notification Permissions
| Permission Type | Description | Required Entitlement | Code Example |
|---|---|---|---|
| alert | Allows display of alerts in the notification center | None | |
| badge | Allows apps to display a badge on the app icon | None | |
| sound | Allows apps to play sounds in notifications | None | |
| carTemplate | Allows use of car template in CarPlay | None | |
| criticalAlert | Allows critical alerts that bypass Do Not Disturb | None | |
| provisional | Allows provisional notification permissions (iOS 12+) | None | |
Note: On iOS 10+, you must request permissions before scheduling any notifications.
Warning: Users can deny permissions in Settings, so always check the granted status before sending notifications.
Permission Summary
- alert: Shows alerts in notification center
- badge: Updates app icon badge count
- sound: Plays sounds for notifications
- carTemplate: Supports CarPlay notification templates
- criticalAlert: Bypasses Do Not Disturb (requires special entitlement)
- provisional: Allows provisional permissions for iOS 12+
10. Using Push Notifications
| Property | Description | Value |
|---|---|---|
| UNNotificationRequest | Represents a notification to be delivered | UNNotificationRequest(identifier: String, content: UNNotificationContent, trigger: UNTrigger?) |
| UNNotificationContent | Defines the content of a notification | UNNotificationContent(title: String, body: String, subtitle: String, sound: UNNotificationSound?, categoryIdentifier: String?) |
| UNNotificationTrigger | Defines when a notification is delivered | UNTimeIntervalTrigger(timeInterval: TimeInterval, repeats: Bool) |
Example: Requesting Push Notification Permissions
import UserNotifications
func requestNotificationPermission() {
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
if granted {
print("Notification permission granted.")
} else {
print("Notification permission denied.")
}
}
}
Example: Scheduling a Push Notification
import UserNotifications
func schedulePushNotification() {
let content = UNMutableNotificationContent()
content.title = "Reminder"
content.body = "Don't forget to complete your task."
content.sound = .default
let trigger = UNTimeIntervalTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: "reminder", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error scheduling notification: \(error)")
} else {
print("Notification scheduled successfully.")
}
}
}
Note: Push notifications require proper setup in your app's
Info.plist and must be enabled via user permission.
Warning: Notifications must be requested at runtime, and users can disable them in system settings.
11. Handling Remote Notifications
| Property | Description | Notes |
|---|---|---|
| UNNotificationRequest | Represents a notification to be delivered | Used to schedule local and remote notifications |
| UNNotificationContent | Defines the content of a notification | Includes title, body, sound, and attachments |
| UNNotificationTrigger | Defines when a notification is delivered | Can be time-based or location-based |
Example: Receiving Remote Notification
import UserNotifications
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Received remote notification: \(userInfo)")
// Process the notification data
if let aps = userInfo["aps"] as? [String: Any] {
if let alert = aps["alert"] as? [String: Any] {
print("Alert title: \(alert["title"] ?? "")")
}
}
completionHandler(.newData)
}
Example: Handling Notification Response
import UserNotifications
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Handle different actions
switch response.actionIdentifier {
case "view":
print("User tapped 'View' action")
// Navigate to relevant screen
case "dismiss":
print("User dismissed notification")
default:
print("Unknown action identifier")
}
completionHandler()
}
Note: Remote notifications must be configured in your app's capabilities and have proper push certificate setup to work correctly.