Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 查找上次激发的UILocalNotification_Ios_Date_Nsdate_Nsdatecomponents - Fatal编程技术网

Ios 查找上次激发的UILocalNotification

Ios 查找上次激发的UILocalNotification,ios,date,nsdate,nsdatecomponents,Ios,Date,Nsdate,Nsdatecomponents,我正在为iOS开发一个使用UILocalNotifications的报警应用程序。到目前为止还不错,直到有人想出了一个主意,显示从用户所在地到他想去的地方的路线 为此,我想我可能会得到最后一个被解雇的UILocalNotification(所有的UILocalNotification都将repeatInterval设置为weekly或daily) 这就是问题的症结所在,因为fireDate是我第一次安排它们:这是我的场景: UILocalNotification* ln = [[

我正在为iOS开发一个使用UILocalNotifications的报警应用程序。到目前为止还不错,直到有人想出了一个主意,显示从用户所在地到他想去的地方的路线

为此,我想我可能会得到最后一个被解雇的UILocalNotification(所有的UILocalNotification都将repeatInterval设置为weekly或daily)

这就是问题的症结所在,因为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];
让我们想象一下:

下周四(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]);
    }