Apple does not offer a way to handle a notification that arrives when your app is closed (i.e. when the user has fully quit the application or the OS had decided to kill it while it is in the background). If this happens, the only way to handle the notification is to wait until it is opened by the user.
Push notification is other than a pop-up you might see on a website or when you're in a mobile app. Pop-ups are only activated if you're using the app or website, whereas push notifications don't require the app to be open. There are also pull notifications, which are activated manually by the user.
Find your notifications in Notification CenterOn the Lock Screen: Swipe up from the middle of the screen. On other screens: Swipe down from the top center. Then you can scroll up to see older notifications, if there are any.
Turn on notifications for Android devicesTap More on the bottom navigation bar and select Settings. Tap Turn on notifications. Tap Notifications. Tap Show notifications.
OK I finally figured out.
In the target settings ➝ Capabilities tab ➝ Background Modes, if you check "Remote Notifications", application:didReceiveRemoteNotification:
will get triggered as soon as notification arrives (as long as the app is in the background), and in that case there is no way to tell whether the user will tap on the notification.
If you uncheck that box, application:didReceiveRemoteNotification:
will be triggered only when you tap on the notification.
It's a little strange that checking this box will change how one of the app delegate methods behaves. It would be nicer if that box is checked, Apple uses two different delegate methods for notification receive and notification tap. I think most of the developers always want to know if a notification is tapped on or not.
Hopefully this will be helpful for anyone else who run into this issue. Apple also didn't document it clearly here so it took me a while to figure out.
I've been looking for the same thing as you and actually found a solution that does not require remote notification to be ticked off.
To check whether user has tapped, or app is in background or is active, you just have to check the application state in
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState == UIApplicationStateActive) {
//app is currently active, can update badges count here
}else if(application.applicationState == UIApplicationStateBackground){
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
}else if(application.applicationState == UIApplicationStateInactive){
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
}
For more info check:
UIKit Framework Reference > UIApplication Class Reference > UIApplicationState
According to iOS / XCode: how to know that app has been launched with a click on notification or on springboard app icon? you have to check for the application state in didReceiveLocalNotification like this:
if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
{
// user has tapped notification
}
else
{
// user opened app from app icon
}
Although it does not make totally sense to me, it seems to work.
If somebody wants it in swift 3.0
switch application.applicationState {
case .active:
//app is currently active, can update badges count here
break
case .inactive:
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
break
case .background:
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
break
default:
break
}
for swift 4
switch UIApplication.shared.applicationState {
case .active:
//app is currently active, can update badges count here
break
case .inactive:
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
break
case .background:
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
break
default:
break
}
I ran into this problem, too — but on iOS 11 with the new UserNotifications
Framework.
Here for me it is like this:
application:didFinishLaunchingWithOptions:
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
userNotificationCenter(_:willPresent:withCompletionHandler:)
userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
If you have "Background Modes" > "Remote notifications" checked == YES, tap on notification event will arrive in:
-(void)userNotificationCenter:(UNUserNotificationCenter *)center **didReceiveNotificationResponse**:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler.
It helped me. Please enjoy :)
There are two Funcs to handle received PushNotification inside PushNotificationManager
class:
class PushNotificationManager: NSObject, MessagingDelegate, UNUserNotificationCenterDelegate{
}
As I tested the first one trigger as soon as Notification arrived
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(UNNotificationPresentationOptions.alert)
//OnReceive Notification
let userInfo = notification.request.content.userInfo
for key in userInfo.keys {
Constants.setPrint("\(key): \(userInfo[key])")
}
completionHandler([])
}
And second one when Tapped on Notification:
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//OnTap Notification
let userInfo = response.notification.request.content.userInfo
for key in userInfo.keys {
Constants.setPrint("\(key): \(userInfo[key])")
}
completionHandler()
}
I also tested it with both ON and OFF states of Remote Notification(in Background Modes)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With