Intereting Posts

Узнать последнюю запущенную UILocalNotification

Я работаю над приложением Alarm для iOS, которое использует UILocalNotifications. До сих пор так хорошо, пока кто-то не придумал показать маршрут, откуда пользователь должен туда, куда он хочет идти.

Для этого я думал, что мог бы получить последнюю утилизацию UILocalNotification (все они имеют repeatInterval, установленный как еженедельно, так и ежедневно).

Здесь возникает вся проблема, поскольку firedate – это первый раз, когда я их планировал: Это мой сценарий:

UILocalNotification* ln = [[UILocalNotification alloc] init]; ln.fireDate = date; // For instance 07/19/2014 10:00:00 (Saturday) ln.repeatInterval = NSDayCalendarUnit; [[UIApplication sharedApplication] scheduleLocalNotification:ln]; UILocalNotification* ln = [[UILocalNotification alloc] init]; ln.fireDate = date; // For instance 07/17/2014 11:00:00 (Thursday) ln.repeatInterval = NSWeekCalendarUnit; [[UIApplication sharedApplication] scheduleLocalNotification:ln]; 

Представьте себе следующее:

Следующий четверг (24.07.2012 11:00:01) Я хочу знать, что последний уволенный UILocalNotification был вторым, который повторяется только по четвергам, а на следующий день я хочу первый, так как он повторяется ежедневно.

Я пробовал сортировать по дате все LocalNotifications без успеха.

Кто-нибудь когда-либо сталкивался с подобной ситуацией раньше?

С уважением

iOS будет отбрасывать локальное уведомление после того, как оно срабатывает, даже если оно планируется повторить через свойство repeatInterval .

[UIApplication sharedApplication].scheduledLocalNotifications фактически возвращает все уведомления, которые планируется уволить в будущем . Таким образом, их fireDate будет установлен на дату в будущем.

После дальнейшего исследования кажется, что fireDate всегда устанавливается на исходное значение, указанное при создании уведомления. Однако следующая дата огня, рассчитанная величина, будет в будущем. Чтобы увидеть это значение, просто запустите po yourNotificationObj в отладчике, и вы увидите следующий тип вывода, который включает следующую дату огня:

{fire date = Суббота, 26 июля 2014 года в 1:42:50 PM Восточное дневное время, часовой пояс = (нуль), интервал повторения = NSMinuteCalendarUnit, количество повторов = UILocalNotificationInfiniteRepeatCount, следующая дата огня = суббота, 26 июля 2014 года, по 1 : 43: 50 PM Eastern Daylight Time, информация для пользователя = (null)}

Как вы рассчитываете следующую дату огня? Пожалуйста, см. Следующий код, взятый из раздела «Как захватить дату следующего события огня из объекта UILocalNotification» :

 NSCalendar *calendar = localNotif.repeatCalendar; if (!calendar) { calendar = [NSCalendar currentCalendar]; } NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease]; // If you use some other repeat interval you would have to change the code accordingly. // If you were to use NSMonthCalendarUnit you would have // to use `components.month = 1' instead components.day = 1; NSDate *nextFireDate = [calendar dateByAddingComponents:components toDate:localnotif.fireDate options:0]; 

Если вы хотите запомнить последнее локальное уведомление, вы должны создать эту логику в своем приложении и сохранить необходимую информацию. Например, вы можете сделать следующее:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; if (localNotification) { [self saveLocalNotification:localNotification]; } return YES; } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { [self saveLocalNotification:notification]; } - (void)saveLocalNotification:(UILocalNotification *)notification { // save information about the last fired local notification on disk } - (UILocalNotification *)lastFiredLocalNotification { // read the information stored on disk by the saveLocalNotification: method // and recreate the notification. I'm just saying recreate the notification // because I don't know what exactly you're trying to do. You // can return anything you want here } 

Используя вышеуказанную настройку, вы можете вызвать метод lastFiredLocalNotification всякий раз, когда вам это нужно.

iOS отбрасывает локальные уведомления после их увольнения. Вы несете ответственность за сохранение этой информации каким-либо другим способом, если вам нужна информация позже.

Если вы хотите, вы можете проверить [UIApplication sharedApplication].scheduledLocalNotifications.firstObject чтобы увидеть следующий запланированный, а затем использовать эту информацию для определения из вашей собственной модели данных, которая была до нее.

Основываясь на ответе @ Sid и некоторых фрагментах кода из SO, я мог бы придумать это решение, которое рассчитывает последнюю уплаченную дату для всех локальных уведомлений, не записывая ее в файл или даже в базу данных. (Хотя писать его где-то не так уж плохо)

заголовок

 #import <UIKit/UIKit.h> @interface UILocalNotification (LastFireDate) - (NSDate *)lastFireDateBeforeDate:(NSDate *)afterDate; @end 

Реализация

 #import "UILocalNotification+LastFireDate.h" @implementation UILocalNotification (LastFireDate) - (NSDate *)lastFireDateBeforeDate:(NSDate *)afterDate { // Check if fire date is in the future: if ([afterDate compare:self.fireDate] == NSOrderedAscending) return [NSDate dateWithTimeIntervalSince1970:0]; // The notification can have its own calendar, but the default is the current calendar: NSCalendar *cal = self.repeatCalendar; if (cal == nil) cal = [NSCalendar currentCalendar]; // Number of repeat intervals between fire date and the reference date: NSDateComponents *difference = [cal components:self.repeatInterval fromDate:self.fireDate toDate:afterDate options:0]; // Add this number of repeat intervals to the initial fire date: NSDate *lastFireDate = [cal dateByAddingComponents:difference toDate:self.fireDate options:0]; // If necessary, subtract one interval: if ([lastFireDate compare:afterDate] == NSOrderedDescending) { switch (self.repeatInterval) { case NSWeekCalendarUnit: difference.week--; break; case NSDayCalendarUnit: difference.day--; break; case NSHourCalendarUnit: difference.hour--; break; default: break; } lastFireDate = [cal dateByAddingComponents:difference toDate:self.fireDate options:0]; } return lastFireDate; } @end 

Применение

  NSDate* date = [NSDate date]; NSArray* arrayNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications]; if([arrayNotifications count]) { NSArray *sorted = [arrayNotifications sortedArrayUsingComparator:^NSComparisonResult(UILocalNotification *obj1, UILocalNotification *obj2) { NSDate *next1 = [obj1 lastFireDateBeforeDate:date]; NSDate *next2 = [obj2 lastFireDateBeforeDate:date]; return [next1 compare:next2]; }]; UILocalNotification* lastLocalNotification = [sorted lastObject]; NSLog(@"%s %@",__PRETTY_FUNCTION__,[lastLocalNotification lastFireDateBeforeDate:date]); } 

Надеюсь, это поможет кому-то, кто сталкивается с той же проблемой

ура