Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect user tap on local notification

I show my local notification like this periodically.

UILocalNotification *notification = [[UILocalNotification alloc]init];
[notification setAlertBody:@"Test test"];
[notification setUserInfo:@{@"test": @"test"}];
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];

I need to detect back that notification and I plan to write here.

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification

It always call that function whether user tap on notification or it automatically call in foreground.

So, I separate using this.

if (application.applicationState == UIApplicationStateActive)

When I show notification center, it become InActive. But, it still call didReceiveLocalNotification. I can't differentiate whether user tap on notification from notification center or because of my periodic posting notification.

How can I really know that I tap on notification (Either from InActive State or Background State) in didReceiveLocalNotification?

like image 329
Khant Thu Linn Avatar asked Oct 06 '15 09:10

Khant Thu Linn


3 Answers

Assuming that I understood your issue correctly, I stumbled on the same obstacle and couldn't find a super clean solution.

So the situation where the following method

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification

is called and applicationState is equal to UIApplicationStateInactive happens in two cases:

  1. the app is in the foreground and the notification has just been fired
  2. the notification has been fired some time ago, notification center is pulled down and user tapped on the notification

One way to distinguish these two cases is to check the notification's fireDate:

notification.fireDate.timeIntervalSinceNow < 0.5

If this expression is true, it's very likely that the first case happened. If the expression is false, it's very likely that the second case happened.

This solution depends on the system delivering the notification without delay and/or the user not being fast enough to click the notification in the notification center under 500ms since the notification's firing. I'm not sure how likely is it for a firing delay to happen. I guess it's possible if the device is under some kind of processing load.

I hope there is a cleaner solution, hopefully someone will share it.

like image 182
Srđan Stanić Avatar answered Oct 20 '22 01:10

Srđan Stanić


First of all, read this from Apple Documentation:

The user taps a custom action button in an iOS 8 notification. In this case, iOS calls either application:handleActionWithIdentifier:forRemoteNotification:completionHandler: or application:handleActionWithIdentifier:forLocalNotification:completionHandler:. In both methods, you get the identifier of the action so that you can determine which button the user tapped. You also get either the remote or local notification object, so that you can retrieve any information you need to handle the action.

The user taps the default button in the alert or taps (or clicks) the app icon. If the default action button is tapped (on a device running iOS), the system launches the app and the app calls its delegate’s application:didFinishLaunchingWithOptions: method, passing in the notification payload (for remote notifications) or the local-notification object (for local notifications). Although application:didFinishLaunchingWithOptions: isn’t the best place to handle the notification, getting the payload at this point gives you the opportunity to start the update process before your handler method is called.

Second, this is how you can differentiate whether didReceiveLocalNotification: is called from active or inactive state:

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    UIApplicationState appState = UIApplicationStateActive;
    if ([application respondsToSelector:@selector(applicationState)])
        appState = application.applicationState;

    if (appState == UIApplicationStateActive)
    {
    }
    else
    {
    }
}
like image 37
Abhinav Avatar answered Oct 20 '22 03:10

Abhinav


  • application:didReceiveLocalNotification:

Sent to the delegate when a running app receives a local notification.

Check this:

iOS UILocalNotification - No delegate methods triggered when app is running in background and the icon is clicked upon notification

like image 20
Gobi M Avatar answered Oct 20 '22 01:10

Gobi M