检测未确认的UILocalNotifications

看起来

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

didReceiveLocalNotification:(UILocalNotification *)notification

仅在用户确认UILocalNotification时触发,例如通过滑动滑块或触摸iOS通知下拉菜单中的条目。

如果用户忽略UILocalNotification并通过单击应用程序图标重新进入应用程序,有没有办法告诉UILocalNotification已经关闭?

我应该提到这实际上仅适用于重复通知,因为可以通过观察总计数来检测非重复通知的触发。 也就是说,当他们开火时, [[UIApplication sharedApplication] scheduledLocalNotifications]消失了。

我正在寻找像…

[[UIApplication sharedApplication] unacknowledgedLocalNotifications]

唉,我找不到类似的东西。

那么,您可以在[[UIApplication sharedApplication] scheduledLocalNotifications]检查您的预定通知。 要查明是否已触发计划的重复通知,请访问fireDate属性以查看为通知设置的初始日期。 然后检查repeatInterval属性。

所以你有2个变量,一个是最初的NSDate ,比如2013-05-08 12:00 ,第二个是重复间隔,让我们说每天。 通过[NSDate date]您将获得我所在的当前日期(瑞典)现在是2013-05-09 22:45 。 所以这意味着有一个用户没有采取行动的通知。

因此,您需要创建一个方法来接受这些参数,然后从初始日期开始迭代,以查看在当前日期时间之前丢失了多少通知。

你会发现NSCalendar的dateByAddingComponents:toDate:选项很有用。

从那以后每个人都有可能继续前进,但我想分享我对这个问题的解决方案。 (抱歉长变量名称……)

这个想法很简单:将来始终保持fireDate。

– 每次调用FininLaunchingWithOptions或didReceiveLocalNotification时,只需取消当前通知,并在将来使用fireDate一个间隔单元重新安排一个新的通知

– 当你的应用程序启动迭代所有预定的通知时,如果将来没有fireDate,你知道它被忽略了

就我而言,通知每周重复一次。 我首先在didFinishLaunchingWithOptions中重新安排任何已确认的通知:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UILocalNotification* localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; if (localNotif != nil) { [NotificationsHelper rescheduleNotification:localNotif]; } } 

并且还在didReceiveLocalNotification中:

 - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *) notification { [NotificationsHelper rescheduleNotification:notification]; } 

在App Launch中,我会检查过去使用fireDate的所有通知:

 - (void)applicationDidBecomeActive:(UIApplication *)application { [self checkLocalNotifications:application]; } 

我的“checkLocalNotifications”function的代码:

 - (void) checkLocalNotifications:(UIApplication *) application { UIApplication* app = [UIApplication sharedApplication]; NSArray* eventArray = [app scheduledLocalNotifications]; for (int i = 0; i < [eventArray count]; i++) { UILocalNotification* notification = [eventArray objectAtIndex:i]; if ([NotificationsHelper wasWeeklyRepeatingNotificationIgnored:notification]) { [NotificationsHelper rescheduleNotification:notification]; NSLog(@"NotificationWasIgnored: %@ %@",notification.alertAction, notification.alertBody ); } } } 

我的“wasWeeklyRepeatingNotificationIgnored”函数的代码:

 + (BOOL) wasWeeklyRepeatingNotificationIgnored:(UILocalNotification*) the_notification { BOOL result; NSDate* now = [NSDate date]; // FireDate is earlier than now if ([the_notification.fireDate compare:now] == NSOrderedAscending) { result = TRUE; } else { result = FALSE; } return result; } 

我的“rescheduleNotification”function的代码:

 + (void) rescheduleNotification:(UILocalNotification*) the_notification { UILocalNotification* new_notification = [[UILocalNotification alloc] init]; NSMutableDictionary* userinfo = [[NSMutableDictionary alloc] init]; [new_notification setUserInfo:userinfo]; [new_notification setRepeatInterval:the_notification.repeatInterval]; [new_notification setSoundName:UILocalNotificationDefaultSoundName]; [new_notification setTimeZone:[NSTimeZone defaultTimeZone]]; [new_notification setAlertAction:the_notification.alertAction]; [new_notification setAlertBody:the_notification.alertBody]; [new_notification setRepeatCalendar:[NSCalendar currentCalendar]]; [new_notification setApplicationIconBadgeNumber:the_notification.applicationIconBadgeNumber]; NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents* weekdayComponents = [gregorian components:NSWeekdayCalendarUnit fromDate:the_notification.fireDate]; NSInteger weekday = [weekdayComponents weekday]; NSDate* next_week = [self addDay:weekday toHourMinute:the_notification.fireDate]; [new_notification setFireDate:next_week]; [[UIApplication sharedApplication] scheduleLocalNotification:new_notification]; [[UIApplication sharedApplication] cancelLocalNotification:the_notification]; } 

如果您的UILocalNotifications增加了应用程序图标徽章编号 (即应用程序图标右上方红色圆圈中的编号),那么有一种非常简单的方法可以检查未确认的UILocalNotifications:只需检查当前applicationIconBadgeNumber是什么:

 - (void)applicationWillEnterForeground:(UIApplication *)application { int unacknowledgedNotifs = application.applicationIconBadgeNumber; NSLog(@"I got %d unacknowledged notifications", unacknowledgedNotifs); //do something about it... //You might want to reset the count afterwards: [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; }