Skip to main content

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
let content = UNMutableNotificationContent()
content.title = "Reminder"
content.body = "Don't forget your meeting"
content.sound = UNNotificationSound.default
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)
let calendar = Calendar.current
let components = DateComponents(hour: 10, minute: 30)
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
UNLocationNotificationTrigger Trigger when entering or exiting a geographic region
let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: 37.7849, longitude: -122.4194), radius: 1000)
let trigger = UNLocationNotificationTrigger(region: region, repeats: false)

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.
let acceptAction = UNNotificationAction(
    identifier: "ACCEPT_ACTION",
    title: "Accept",
    options: [.foreground]
)
UNNotificationCategory Groups related actions together for notifications.
let meetingCategory = UNNotificationCategory(
    identifier: "MEETING_INVITATION",
    actions: [acceptAction, declineAction],
    intentIdentifiers: [],
    options: []
)

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
import UserNotifications

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert]) { granted, error in
    if granted {
        print("Alert permission granted")
    } else {
        print("Alert permission denied")
    }
}
badge Allows apps to display a badge on the app icon None
center.requestAuthorization(options: [.badge]) { granted, error in
    if granted {
        print("Badge permission granted")
    } else {
        print("Badge permission denied")
    }
}
sound Allows apps to play sounds in notifications None
center.requestAuthorization(options: [.sound]) { granted, error in
    if granted {
        print("Sound permission granted")
    } else {
        print("Sound permission denied")
    }
}
carTemplate Allows use of car template in CarPlay None
center.requestAuthorization(options: [.carTemplate]) { granted, error in
    if granted {
        print("Car template permission granted")
    } else {
        print("Car template permission denied")
    }
}
criticalAlert Allows critical alerts that bypass Do Not Disturb None
center.requestAuthorization(options: [.criticalAlert]) { granted, error in
    if granted {
        print("Critical alert permission granted")
    } else {
        print("Critical alert permission denied")
    }
}
provisional Allows provisional notification permissions (iOS 12+) None
center.requestAuthorization(options: [.provisional]) { granted, error in
    if granted {
        print("Provisional permission granted")
    } else {
        print("Provisional permission denied")
    }
}
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.

Was this article helpful?