Detect Unverified UILocalNotifications

It seems that

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

and

didReceiveLocalNotification:(UILocalNotification *)notification

run only if the user confirms the UILocalNotification, for example, by scrolling the slider or touching the entry in the iOS notification drop-down list.

Is it possible to say that UILocalNotification is disabled if the user ignores UILocalNotification and re-enters the application by simply clicking on the application icon?

I should mention that this only applies to repeated notifications, because shooting of non-repeated notifications can be detected by observing the total. That is, when they shoot, it disappears from [[UIApplication sharedApplication] scheduledLocalNotifications] .

I'm looking for something like ..

[[UIApplication sharedApplication] unacknowledgedLocalNotifications]

Alas, I can not find anything like it.

+6
source share
3 answers

Well, you can check your scheduled notifications inside [[UIApplication sharedApplication] scheduledLocalNotifications] . To find out if the scheduled re-notification has activated access to the fireDate property to find out what the start date for the notification was. Then check the repeatInterval property.

So, you have 2 variables, one of them is the initial NSDate , say 2013-05-08 12:00 , and the second is the repetition interval, say, daily. And by completing [NSDate date] , you will get the current date where I am (in Sweden) now 2013-05-09 22:45 . Thus, this means that there is one notification that the user has not acted on.

So, you will need to create a method that will take these arguments, and then repeat from the start date to find out how many notifications have been missed before the current time and time.

You will find NSCalendar dateByAddingComponents: toDate: options useful.

+5
source

Everything has changed since then, but I would like to share my solution to this problem. (Sorry for the names of long variables ...)

The idea is simple: always keep firedate in the future.

- this time the FinishLaunchingWithOptions or didReceiveLocalNotification function is called, just cancel your current notification and transfer the new one using the FireDate time unit in the future

-When your application starts iterating over all scheduled notifications, if firedate will not be in the future, you know that it was ignored

In my case, notifications have a weekly repetition interval. I first transfer any confirmed notifications to the didFinishLaunchingWithOptions file:

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

And also in didReceiveLocalNotification:

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

In App Launch, I check all notifications for anyone with FireDate in the past:

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

Code for my function "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 ); } } } 

The code for my function isWeeklyRepeatingNotificationIgnored:

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

Code for my 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]; } 
+2
source

If your UILocalNotifications increase the number of the application icon icon (i.e. the number in the red circle in the upper right corner of the application icon), then there is a ridiculously easy way to check for unrecognized UILocalNotifications: just check that the current 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]; } 
0
source

Source: https://habr.com/ru/post/944654/


All Articles