Ios 查找上次激发的UILocalNotification
我正在为iOS开发一个使用UILocalNotifications的报警应用程序。到目前为止还不错,直到有人想出了一个主意,显示从用户所在地到他想去的地方的路线 为此,我想我可能会得到最后一个被解雇的UILocalNotification(所有的UILocalNotification都将repeatInterval设置为weekly或daily) 这就是问题的症结所在,因为fireDate是我第一次安排它们:这是我的场景:Ios 查找上次激发的UILocalNotification,ios,date,nsdate,nsdatecomponents,Ios,Date,Nsdate,Nsdatecomponents,我正在为iOS开发一个使用UILocalNotifications的报警应用程序。到目前为止还不错,直到有人想出了一个主意,显示从用户所在地到他想去的地方的路线 为此,我想我可能会得到最后一个被解雇的UILocalNotification(所有的UILocalNotification都将repeatInterval设置为weekly或daily) 这就是问题的症结所在,因为fireDate是我第一次安排它们:这是我的场景: UILocalNotification* ln = [[
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];
让我们想象一下:
下周四(2014年7月24日11:00:01),我想知道上一次发布的UILocalNotification是第二个只在周四重复的通知,第二天我想要第一个,因为它每天都重复
我尝试按日期对所有本地通知进行排序,但没有成功
以前有没有人遇到过类似的情况
iOS会在本地通知被触发后丢弃它们。如果以后需要这些信息,您有责任以其他方式维护这些信息
如果需要,可以检查
[UIApplication sharedApplication].scheduledLocalNotifications.firstObject
以查看计划的下一个,然后使用该信息从您自己的数据模型中确定之前的数据模型。iOS将在发出本地通知后丢弃该通知,即使该通知计划通过repeatInterval
属性重复
[UIApplication sharedApplication].scheduledLocalNotifications
实际上返回计划在将来启动的所有通知。因此,他们的fireDate
将设置为将来的日期
经过进一步调查,似乎fireDate
始终设置为创建通知时指定的原始值。但是,下一个火灾日期(计算值)将在未来。要查看此值,只需在调试器中运行yourNotificationObj,您将看到以下类型的输出,其中包括下一个触发日期:
{火灾日期=7月6日星期六
2014年12月26日东部夏令时下午1:42:50,时区=(空),
重复间隔=NSMinuteCalendarUnit,重复计数=
UILocalNotificationInfiniteRepeatCount,下一个火灾日期=周六,
2014年7月26日东部夏令时下午1:43:50,用户信息=(空)}
你如何计算下一个火灾日期?请参阅以下代码摘自:
如果您想记住上次触发的本地通知,则必须将该逻辑构建到应用程序中并保存所需信息。例如,您可以执行以下操作:
- (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
方法。基于@Sid的答案和来自的一些代码片段,因此我可以提出此解决方案,它可以计算所有本地通知的上次触发日期,而无需将其写入文件甚至数据库。(尽管把它写在某个地方不是个坏主意)
标题
#import <UIKit/UIKit.h>
@interface UILocalNotification (LastFireDate)
- (NSDate *)lastFireDateBeforeDate:(NSDate *)afterDate;
@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]);
}
希望它能帮助那些面临同样问题的人
干杯我已经检查过了,似乎iOS只会丢弃未设置重复间隔的通知。在我的场景中,所有本地通知都已设置,因为我可以在它们触发后列出它们。+1。感谢您发布您的解决方案。这对未来的访问者非常有帮助。@PauloMiguelAlmeida请您根据时区修改此代码,我在UILocalNotification中指定了defaultTimeZone,我正在通过更改时区来计算日期,但我得到了错误的结果,请帮我根据defaultTimeZone修改您的代码。感谢you@S.J实际上,只要在UILocationNotification和此category方法上使用相同的时区,那么使用哪个时区并不重要。
#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]);
}