iOS Notifications Handling
=====================================
Introduction
In this article, we will explore how to handle notifications on an iOS application. We’ll dive into the world of Universal Notifications, which allows us to manage and display notifications in a centralized way, making it easier to create a seamless user experience.
Understanding Universal Notifications
Universal Notifications is a feature introduced by Apple in iOS 13 that enables developers to manage and display notifications across multiple applications. This allows for more control over how notifications are displayed and provides a better user experience.
Getting Started with Universal Notifications
To start using Universal Notifications, you’ll need to register your application for push notifications through the App Store Connect portal. Once registered, you can use the Push Notification service to send notifications to your users.
Receiving Notifications
When a notification is received, it’s delivered to the system’s Notification Center. The app that initiated the notification will receive a call from the system, indicating that a notification was received. This call includes information about the notification, such as its title, body, and sound.
// iOS 13 and later
import UserNotifications
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Register for push notifications
UNUserNotificationCenter.current().delegate = self
// Request authorization to display notifications
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound])
}
@objc func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler handler: (@escaping (UNNotificationPresentationOptions) -> Void)) {
// Handle the notification
print("Notification received")
// Present the notification
let options = notification.request.trigger as! UNNotificationTrigger
let dateMatch = options.dateComponents
let userDateMatch = Date()
if dateMatch == userDateMatch {
// Handle today's notifications only
print("Today's notification")
} else {
// Handle other dates
print("Other notification")
}
}
@objc func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler handler: (@escaping Void)) {
// Handle the notification response
print("Notification responded")
// Present the notification
let options = response.notification.request.trigger as! UNNotificationTrigger
let dateMatch = options.dateComponents
let userDateMatch = Date()
if dateMatch == userDateMatch {
// Handle today's notifications only
print("Today's notification")
} else {
// Handle other dates
print("Other notification")
}
}
}
Presenting Notifications
To present a notification, you’ll need to use the UNNotificationPresentationOptions enum and set the corresponding options for your notification. The options determine how the notification is displayed, such as whether it’s presented as an alert or a badge.
// iOS 13 and later
import UserNotifications
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Present a notification
let content = UNNotificationContent()
content.title = "Hello"
content.body = "This is a test notification"
content.sound = UNNotificationSound.default
// Set presentation options
let options = UNNotificationPresentationOptions(rawValue: [.alert, .sound])
// Request authorization to display notifications
UNUserNotificationCenter.current().requestAuthorization(options: options)
}
@objc func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler handler: (@escaping (UNNotificationPresentationOptions) -> Void)) {
print("Notification presented")
// Present the notification
let content = notification.request.content
print(content.title)
}
}
Storyboard Navigation
Now that we’ve explored Universal Notifications, let’s dive into how to navigate between views using storyboards. When a user taps on a notification, you’ll want to present them with the corresponding view controller.
To do this, you can use the performSegue method to push a new view controller onto the navigation stack. However, in your case, you mentioned that you have three pushes of a view controller onto a navigation controller by the user.
Using Storyboard Segues
One way to solve this problem is to use storyboard segues. You can create a segue between two view controllers and then programmatically push one segue onto another using the performSegue method.
// Create a segue in your storyboard
StoryboardSegue(type:StoryboardSegue.Type, identifier: "segueToChat", destination: ChatViewController())
Then, you can use the following code to push one segue onto another:
// Programmatically push a segue
let segue = NavigationController segues["segueToChat"]
if segue != nil {
self.navigationController?.performSegue(withIdentifier: segue.identifier, sender: self)
} else {
print("Segue not found")
}
Using the rootViewController Property
Another way to solve this problem is to use the rootViewController property of the navigation controller. When a user taps on a notification, you can present them with the corresponding view controller using the rootViewController.
// Present a view controller using the root view controller
let chatViewController = ChatViewController()
self.rootViewController?.present(chatViewController, animated: true, completion: nil)
However, this approach requires that you have set the rootViewController before presenting it.
Using UserNotificationsDelegate
To determine which segue to present, you can use the userNotificationCenter(_:willPresent:) method of the UNUserNotificationCenterDelegate. This method is called when a notification is received and allows you to handle the notification accordingly.
// Handle notifications using the user center
@objc func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler handler: (@escaping (UNNotificationPresentationOptions) -> Void)) {
// Present a view controller based on the notification's identifier
switch notification.request.trigger as! UNNotificationTrigger {
case .date(let date):
if Date().timeIntervalSince(date) < 60 * 60 { // last hour
self.navigationController?.performSegue(withIdentifier: "segueToChat", sender: self)
} else {
print("Other notification")
}
default:
print("Other notification")
}
}
Conclusion
Handling notifications on an iOS application requires a combination of understanding Universal Notifications and navigating between views using storyboards. By using the performSegue method, storyboard segues, the rootViewController property, or the userNotificationCenter(_:willPresent:) method, you can present users with the corresponding view controller when they tap on a notification.
However, there is no straightforward way to push one segue onto another without manual intervention. Instead, you’ll need to use a combination of methods to determine which segue to present based on the notification’s identifier or other factors.
By following this guide, you should be able to handle notifications in your iOS application and provide users with a seamless experience.
Additional Resources
- Apple Developer Documentation: User Notifications
- Apple Developer Documentation: Storyboard Segues
- Stack Overflow: How to push one segue onto another in iOS Navigation Controller
Last modified on 2023-08-21