检测将要触发的下一个UILocalNotification

way*_*way 4 cocoa-touch nsarray ios uilocalnotification

有没有办法找到NSDate下一个将触发的本地通知?

例如,我设置了三个本地通知:

通知#1:设置为昨天下午3:00开始,每天重复间隔.

通知#2:今天下午5点开始点火,每天重复一次.

通知#3:明天下午6点开始,每天重复一次.

鉴于当前是下午4:00,将触发的下一个本地通知是通知#2.

如何检索此本地通知并获取其日期?

我知道我可以在一个数组中检索这些本地通知,但是如何根据今天的日期获取下一个?

Mar*_*n R 11

您的任务的主要目标是确定每个通知的给定日期之后的"下一个开火日期".a的NSLog()输出UILocalNotification显示了下一个发布日期,但遗憾的是它似乎不能用作(公共)属性.

我从/sf/answers/1311131461/(经过小改进)中获取了代码并将其重写为类别方法UILocalNotification.(这不完美.它不包括已为通知分配时区的情况.)

@interface UILocalNotification (MyNextFireDate)
- (NSDate *)myNextFireDateAfterDate:(NSDate *)afterDate;
@end

@implementation UILocalNotification (MyNextFireDate)
- (NSDate *)myNextFireDateAfterDate:(NSDate *)afterDate
{
    // Check if fire date is in the future:
    if ([self.fireDate compare:afterDate] == NSOrderedDescending)
        return self.fireDate;

    // 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 *nextFireDate = [cal dateByAddingComponents:difference
                                                     toDate:self.fireDate
                                                    options:0];

    // If necessary, add one more:
    if ([nextFireDate compare:afterDate] == NSOrderedAscending) {
        switch (self.repeatInterval) {
            case NSDayCalendarUnit:
                difference.day++;
                break;
            case NSHourCalendarUnit:
                difference.hour++;
                break;
            // ... add cases for other repeat intervals ...
            default:
                break;
        }
        nextFireDate = [cal dateByAddingComponents:difference
                                            toDate:self.fireDate
                                           options:0];
    }
    return nextFireDate;
}
@end
Run Code Online (Sandbox Code Playgroud)

使用它,您可以根据下一个开火日期对一组本地通知进行排序:

NSArray *notifications = @[notif1, notif2, notif3];

NSDate *now = [NSDate date];
NSArray *sorted = [notifications sortedArrayUsingComparator:^NSComparisonResult(UILocalNotification *obj1, UILocalNotification *obj2) {
    NSDate *next1 = [obj1 myNextFireDateAfterDate:now];
    NSDate *next2 = [obj2 myNextFireDateAfterDate:now];
    return [next1 compare:next2];
}];
Run Code Online (Sandbox Code Playgroud)

现在sorted[0]将是下一个触发的通知.