I would like to give an example about handling remote push notifications.
All will be in AppDelegate.swift file;
First of all get your token after registration from this function to can send Remote Push Notifications (RPM) from your servers or provider:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Send device token that accepted to retrieve remote notifications to server
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
NSLog("APNs registration success, device token: \(token)")
}
Check remote notification info is exist in launch options inside didFinishLaunchWithOptions
method to know did app launched by tapping notification alert like this:
// Check if there any user info about remote notifications in 'launchOptions'
/// Get user your data from userInfo dictionary if you need
if let userInfo = launchOptions?[.remoteNotification] as? [String: AnyObject],
let exmplValue = userInfo["yourValue"] as? String {
NSLog("[AppDelegate] - Info: App launched by tapping notification alert. We have new value: \(exmplValue)")
/// Here you can change rootVC or storing some values to process it in your mainVC etc.
}
Then implement didReceiveRemoteNotification
function like in below to handle push notifications in both state active and inactive:
/// This function made for handling push notifications when app running (both states active or inactive)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
/// Hide badge number if it exist
application.applicationIconBadgeNumber = 0
/// Get user your data from userInfo dictionary if you need
guard let aps = userInfo["aps"] as? [String: Any],
let alert = aps["alert"] as? [String: Any],
let title = alert["title"] as? String,
let body = alert["body"] as? String,
let exampleValue = userInfo["example"] as? String else {
NSLog("[AppDelegate] - Warning: user info missing aps or other data.")
return
}
/// Check current application state
if UIApplication.shared.applicationState == .active {
// Your app in foreground, you can ask user to want to take action about what you want to do.
} else {
// Your app in background at most in inactive mode, user when taps on notification alert app will become active so you can do whatever you want directly
}
}
Bonus:
Implement UNUserNotificationCenterDelegate
in your AppDelegate.swift file then inside didFinishLaunchWithOptions
confirm to delegate of notification center like this: UNUserNotificationCenter.current().delegate = self
Finally override this function to adjusting badge, sound, alert of notification that will present.
// Assign delegate to show LPN or RPN badge, alert, sound
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
/// I would like to notify user by sound only when app is active
/// otherwise show notification (alert, badge, sound)
if UIApplication.shared.applicationState == .active {
completionHandler(.sound)
} else {
completionHandler([.alert, .badge, .sound])
}
}
Please remember in these examples i don't implemented silent (background) notifications because of when i activate silent notifications my app handling all type of notifications inside below function and i cannot understand my app launched by tapping RPM or something else, briefly am not familiar with this case so if you need it you must add background modes capability and check Remote Notifications in your Targets -> Your App -> Signing& Capabilities, then implement this function to handle RPM:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
<#code#>
}
Happy coding