检测用户点击本地通知

Detect user tap on local notification

我会定期显示这样的本地通知。

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

我需要检测回那个通知,我打算写在这里。

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

无论用户点击通知还是在前台自动调用,它总是调用该函数。

所以,我用这个分开。

if (application.applicationState == UIApplicationStateActive)

当我显示通知中心时,它变成了InActive。但是,它仍然调用 didReceiveLocalNotification。我无法区分用户是从通知中心点击通知还是因为我定期发布通知。

我怎么才能真正知道我点击了 didReceiveLocalNotification 中的通知(来自非活动状态或后台状态)?

  • 应用程序:didReceiveLocalNotification:

当 运行 应用收到本地通知时发送给代理人。

检查这个:

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

首先,阅读来自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.

第二个,这是区分didReceiveLocalNotification:是从活动状态还是非活动状态调用的方法:

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

    if (appState == UIApplicationStateActive)
    {
    }
    else
    {
    }
}

使用 KVO key-value-observing 在点击按钮时了解并执行某些操作。

假设我正确理解了您的问题,我偶然发现了同样的障碍,但找不到超级干净的解决方案。

所以出现下面方法的情况

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

被调用并且 applicationState 等于 UIApplicationStateInactive 在两种情况下发生:

  1. 应用程序在前台,通知刚刚被触发
  2. 通知已在一段时间前触发,通知中心被下拉,用户点击了通知

区分这两种情况的一种方法是检查通知的触发日期:

notification.fireDate.timeIntervalSinceNow < 0.5

如果这个表达式为真,那么很可能是第一种情况发生了。如果表达式为假,很可能是第二种情况。

此解决方案取决于系统是否延迟发送通知 and/or 用户在通知触发后的 500 毫秒内没有足够快地点击通知中心的通知。我不确定触发延迟发生的可能性有多大。我想如果设备处于某种处理负载下,这是可能的。

我希望有一个更干净的解决方案,希望有人能分享它。