繁体   English   中英

预定的本地通知是不定期的

[英]Scheduled local notifications are irregular

我的iOS本地通知存在严重问题。 我有一个用Objective-C编写的应用程序,该应用程序允许用户选择触发通知的时间以及一周中的几天(应该在指定时间的指定日期每周触发)。 我在一天中触发通知的时间没有问题,可以正常工作。 但是,当我指定应该触发的日期时,会发生奇怪的事情。 首先,它们会触发一次,但是每天触发一次,而不只是指定的日期。 然后,在第一个星期后,他们每天开火,但不仅开火一次。 相反,它们会触发指定次数的次数(因此,如果选择了星期日,星期一和星期二,则每天用户将在指定时间收到3个连续的通知)。

这是我用来设置通知的代码。

轻按“保存”按钮后,首先发生的事情是清除所有通知,为新通知让路。

//cancels all notifications upon save
[[UIApplication sharedApplication] cancelAllLocalNotifications];

接下来,我使用NSDate,NSCalendar和NSCalendarComponents来获取当前时间的详细信息以及UIPicker的组件(用于选择一天中的时间)

NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekOfYear|NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:now];//get the required calendar units


然后,我从UIPicker获取时间单位,并从选择器获取实际时间。

NSDateComponents *pickedComponents = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:picker.date];
NSDate *minuteHour = [calendar dateFromComponents:pickedComponents];
[[NSUserDefaults standardUserDefaults] setObject:minuteHour forKey:@"FireTime"];


之后,我设置要在通知中显示的文本

NSString *reminder = @"Reminder text!";

接下来是通知的实际设置。 它们都是相同的(当然,星期几会更改),所以我只显示星期日。

//sunday
UILocalNotification *localNotificationSunday = [[UILocalNotification alloc] init];
if ([sundayTempStatus isEqual:@"1"])
{

    //permanently save the status
    [[NSUserDefaults standardUserDefaults] setObject:@"1" forKey:@"Sunday"];

    //set up notifications
    //if it is past sunday, push next week
    if (components.weekday > 1)
    {
        components.day = components.day + 7; //if already passed sunday, make it next sunday
    }

    //components.day = 1;
    components.hour = [pickedComponents hour];
    components.minute = [pickedComponents minute];

    NSDate *fireDate = [calendar dateFromComponents:components];

    localNotificationSunday.fireDate = fireDate;
    localNotificationSunday.alertBody = reminder;
    localNotificationSunday.timeZone = [NSTimeZone systemTimeZone];
    localNotificationSunday.repeatInterval = NSCalendarUnitWeekOfYear;
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotificationSunday];
}
else
{
    [[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"Sunday"];
}


非常感谢您的帮助,如果需要任何其他信息或代码,我们将很乐意提供。

当代码变得重复时,它常常变得更容易出错。 我已经写出了一种简单的方法,应该注意提醒的安排。

- (void)scheduleNotificationForDayOfWeek:(int)dayOfWeek withPickedComponents:(NSDateComponents *)pickedComponents andReminderString:(NSString *)reminderString {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    UILocalNotification *notification = [[UILocalNotification alloc] init];

    NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekOfYear|NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:[NSDate date]];
    components.hour = [pickedComponents hour];
    components.minute = [pickedComponents minute];

    NSDateComponents *additionalComponents = [[NSDateComponents alloc] init]; // to be added onto our date
    if ([components weekday] < dayOfWeek) {
        additionalComponents.day = (dayOfWeek - [components weekday]); // add the number of days until the next occurance of this weekday
    } else if ([components weekday] > dayOfWeek) {
        additionalComponents.day = (dayOfWeek - [components weekday] + 7); // add the number of days until the next occurance of this weekday
    }

    NSDate *fireDate = [calendar dateFromComponents:components];
    fireDate = [calendar dateByAddingComponents:additionalComponents toDate:fireDate options:0]; // add on our days

    notification.fireDate = fireDate;
    notification.alertBody = reminderString;
    notification.timeZone = [NSTimeZone systemTimeZone];
    notification.repeatInterval = NSCalendarUnitWeekOfYear;
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

这实际上很简单。 用星期几来调用它(例如0 =星期日,1 =星期一),它将安排该天的重复提醒。 我无法使用周日代码在测试中重现您的问题,因此我认为在重复该代码的某个地方您肯定出错了。

这种方法简化了开火日期的获取。 它使用NSDateComponents轻松获取该工作日的下一次出现。 这样称呼: [self scheduleNotificationForDayOfWeek:0 withPickedComponents:pickedComponents andReminderString:@"Hello, world!"]; (它将在每个星期日在指定组件上显示“ Hello,world!”)

使用此代码段,您应该能够摆脱代码中大多数重复的语句,并简化设置通知的方式。 对我来说,这很完美。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM