每月一次的Objective-C月度通知

时间:2014-04-17 03:53:58

标签: ios objective-c notifications localnotification

我的应用中有一个通知系统,允许用户设置多个通知,它们可以是:

  • 每日
  • 每周
  • 每月

前两个是好的,但在第三个我有问题。 假设我们在3月份,并且用户将通知设置为在该月的31日触发。通知安排正确,但如果我们在4月(30天)的地方,例如通知安排在5月1日。

我有两个问题:

  • 如何在一个月的最后一天安排通知?或者将它们设置为在接下来的几个月中优雅地处理此案例
  • 如果3月31日的通知正确安排,下一个通知是否会安排在4月30日,然后是5月31日?我的猜测是否定的,将于3月31日,4月1日和4月31日举行。

安排多个通知对我来说不是一个选项,因为苹果有一个限制,如果用户有6个月通知(6x12)并且可能有更多通知,则可以轻松达到限制。

谢谢,

塞尔吉奥

修改

抱歉,我没有正确解释自己。 我没有在正确的日期设置通知的问题。但我对重复的工作方式有疑问。如果我在3月31日开始每月31日设置一个通知(假设我们在3月份),那么第一个会在正确的日期出现,但4月会发生什么?

再次感谢。

4 个答案:

答案 0 :(得分:2)

您可以使用以下方法获取特定日期的月份的最后一天

-(NSDate*)lastDayOfMonthOfDate:(NSDate *)date
{
    NSInteger dayCount = [self numberOfDaysInMonthCountForDate:date];

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

    [calendar setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];

    NSDateComponents *comp = [calendar components:
                              NSYearCalendarUnit |
                              NSMonthCalendarUnit |
                              NSDayCalendarUnit fromDate:date];

    [comp setDay:dayCount];

    return [calendar dateFromComponents:comp];
}

-(NSInteger)numberOfDaysInMonthCountForDate:(NSDate *)date
{
    NSCalendar *calendar = [[NSCalendar alloc]   initWithCalendarIdentifier:NSGregorianCalendar];

   [calendar setTimeZone:[NSTimeZone timeZoneWithName:TIMEZONE]];

    NSRange dayRange = [calendar rangeOfUnit:NSDayCalendarUnit
                                      inUnit:NSMonthCalendarUnit
                                     forDate:date];

    return dayRange.length;
}

从这些方法中查找最后一天并安排当天的通知

来源:Getting the last day of a month

答案 1 :(得分:0)

-[NSCalendar rangeOfUnit:inUnit:forDate:]会告诉您特定日期组件在特定日期的上下文中可以在较大组件中执行的最小值和最大值。

如果您使用NSDayCalendarUnitNSMonthCalendarUnit,则结果的length将是包含传递日期的月份的最后一天。

例如:

NSCalendar * c = [NSCalendar currentCalendar];
NSRange aprilRanger = [c rangeOfUnit:NSDayCalendarUnit 
                              inUnit:NSMonthCalendarUnit 
                             forDate:[NSDate date]];

NSLog(@"%lu", aprilRanger.length);

NSDateComponents * minusTwoMonths = [NSDateComponents new];
[minusTwoMonths setMonth:-2];
NSDate * febDay = [c dateByAddingComponents:minusTwoMonths 
                                  toDate:[NSDate date] 
                                 options:0];
NSRange febRange = [c rangeOfUnit:NSDayCalendarUnit 
                           inUnit:NSMonthCalendarUnit 
                          forDate:febDay];

NSLog(@"%lu", febRange.length);

产地:

  

30
  28

当闰日等奇怪的事情发生时,这将给你正确答案。

答案 2 :(得分:0)

我必须做的是: 检查当前月份是否有用户请求的日期(最多31个)。

  • 如果没有,那么在最后一天安排当前月份的正常通知,然后在下个月安排每月一次,操作系统将处理其余的。

注意:如果当前月份没有请求的日期(30日元),下一个月肯定会有(3月31日)。

  • 如果确实如此,则按当月安排月度。

答案 3 :(得分:-1)

嘿,这不是什么大不了的事。

在通知对象集repeatIntervalNSMonthCalendarUnit

UILocalNotification *notify = [ [UILocalNotification alloc] init ];
notify.fireDate = notificationDate;
notify.repeatInterval = NSMonthCalendarUnit;
// use NSDayCalendarUnit, NSWeekCalendarUnit for daily or weekly respectively.

由于 damithH