This question already has answers here:
didReceiveRemoteNotification not called, iOS 10
(9 answers)
Closed 4 years ago.
I have the following appDelegate:
import UIKit
import CoreData
import UserNotifications
#available(iOS 11.0, *)
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate
{
var window: UIWindow?
...
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any])
{
print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
}
I am using ios11 and swift 4.1 but the notification gets fired off correctly. But when I tap it I can't grab it in the app. Why? I am using xcode 9.4.1. Thanks.
The app is in the background and when the notification is tapped the app opens up.
Hello #cdub You should use usernotificatioCenter
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
// do code here to show notification alert in for-ground mode
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
//your notification handling code here
}
Related
There are many articles regarding how to take user to a specific view when he/she taps on a push notification using App Delegate. But is it possible to do this using only the SwiftUI App Lifecycle?
There isn't away using only SwiftUI. You will have to use the AppDelegate to respond to notifications.
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
UNUserNotificationCenter.current().delegate = self
return true
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
print("Notification received with identifier \(notification.request.identifier)")
completionHandler([.banner, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
// do what you want here
}
}
I have implemented the push notification in the app. I am getting callbacks on the following delegate method whenever the push comes.
func application(_: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
I have implemented the following delegate method To show the push notification when the app is in the foreground.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler([.alert, .badge, .sound])
}
Unfortunately, it is not working every time. Irrespective of the app state I'm getting the callback on didReceiveRemoteNotification method. Is there any particular reason for this behavior? Am I missing something?
Thanks in advance
I think you have to use the userNotificationCenter with the "didReceive response" signature instead of the application(didReceiveRemoteNotification userInfo:..)
// MARK: Notification handling
// If the app is in the background
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let id = response.notification.request.identifier
print("Received notification with ID = \(id)")
completionHandler()
}
// If the app is in the foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let id = notification.request.identifier
print("Received notification with ID = \(id)")
completionHandler([.sound, .alert])
}
Also have your AppDelegate be UNUserNotificationCenter delegate.
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
}
.
.
.
}
UNUserNotificationCenterDelegate is not working when is remove from background. It is working fine while app stays in foreground and background.
Here is code
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let rootViewController = self.window!.rootViewController as! UINavigationController
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let profileViewController = mainStoryboard.instantiateViewController(withIdentifier: "SampleViewController") as! SampleViewController
rootViewController.pushViewController(profileViewController, animated: true)
completionHandler()
}
}
When app is remove from background delegate method is not called. Please help me out
When adding UserNotifications framework to a project, here are 5 things to check:
1) If you are dealing with remote notifications, be sure you have enabled that in your project's capabilities settings page of Xcode.
See figure 1
If that gives you an error, you probably need to log into your apple developer account and create a key with push notification credentials. The end result gives you a .p8 file to download. The creation of this file will clear up the error. The file itself is needed on the server that sends push notifications to your app/device. If you need help with this, check out this tutorial.
2) Add import line to the top of your AppDelegate file
import UserNotifications
3) Add UNUserNotificationCenterDelegate to your AppDelegate class declaration line.
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {...
4) Set UNUserNotificationCenter delegate to self in the application:didFinishLaunchingWithOptions method.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//...
UNUserNotificationCenter.current().delegate = self
//...
return true
}
5) Add your delegate functions (if you want to use them)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
NSLog("Application delegate method userNotificationCenter:didReceive:withCompletionHandler: is called with user info: %#", response.notification.request.content.userInfo)
//...
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
NSLog("userNotificationCenter:willPresent")
//...
completionHandler([.alert])
}
Hope that helps.
check didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? method. When user taps a notification banner (and the app is terminated) the app is started, this method is called and launchOptions contains notification info. Therefore you can understand (by checking the launchOptions) that the app is launched by tapping on notification banner and navigate user wherever you want to
I want to find out which method is triggered when a terminated application receives a notification from my server. The application is being developed through Swift 4, my Deployment Target is 10.3 and Firebase is used to send notifications to users.
I've configured my application in AppDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
Messaging.messaging().delegate = self
UNUserNotificationCenter.current().delegate = self
}
Additionally, I created the extension:
#available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
}
}
When the app receives a notification and it's running or it's in background, the method "willPresent" is called and when the user taps on the notification and decide to open it, the method "didReceive" is called. No method is triggered if the application is terminated.
Am I doing something wrong?
I recently set up notifications on my application, I can send via php and no worries, everything works fine.
Since last week, I am trying to find out if a push notification is received by the phone or not..
I can know when someone clicks on it but if the person does not click on it and prefer to open the application, it does not work..
Is there not a simple function that can tell me if a notification has just been received by the application ?
In my AppDelegate.swift :
import UIKit
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Check if launched from notification
if let notification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: AnyObject] {
//print(notification)
window?.rootViewController?.present(ViewController(), animated: true, completion: nil)
}
else{
//print("ici ?")
registerForRemoteNotification()
}
return true
}
...
//Called when a notification is delivered to a foreground app.
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
//Called to let your app know which action was selected by the user for a given notification.
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
completionHandler()
}
...
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
**print("here ?")**
switch((application.applicationState)){
case UIApplicationState.inactive:
print("Inactive")
//Show the view with the content of the push
completionHandler(.newData)
case UIApplicationState.background:
print("Background")
//Refresh the local model
completionHandler(.newData)
default:
print("Active")
//Show an in-app banner
completionHandler(.newData)
break
}
}
}
Problem : I never pass in didReceiveRemoteNotification :/
The "print here" is never displayed.
I have a mistake on this line :
Instance method
'application(application:didReceiveRemoteNotification:fetchCompletionHandler:)'
nearly matches optional requirement
'application(_:didReceiveRemoteNotification:fetchCompletionHandler:)'
of protocol 'UIApplicationDelegate'
But I do not understand :/
Do you have an idea ?
Thx for your help ^^
It's rather common mistake since the conversion to Swift 3 - you're using Swift 2 method.
The right signature of this method in Swift 3 is:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
print("here?")
}