首页 文章

检测未确认的UILocalNotifications

提问于
浏览
6

看起来

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

didReceiveLocalNotification:(UILocalNotification *)notification

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

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

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

我正在寻找像......

[[UIApplication sharedApplication] unacknowledgedLocalNotifications]

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

3 回答

  • 0

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

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

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

    你会发现 NSCalendar s dateByAddingComponents:toDate:options很有用 .

  • 2

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

    这个想法很简单:将来始终保持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”功能的代码:

    - (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”功能的代码:

    + (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];
    }
    
  • 5

    If your UILocalNotifications increment the application icon badge number (即应用程序图标右上角红色圆圈中的数字),然后有一种非常简单的方法来检查未确认的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];
    
    }
    

相关问题