Как запланировать уведомление, которое будет повторяться с определенной частотой по истечении определенного времени
Я не вижу поддержки для планирования такого рода уведомлений, т.е. оно повторяется только по прошествии определенного времени. Проблема в том, что расписание срабатывает сразу, не дожидаясь точного времени, хотя повторяется правильно.
например, вот код для планирования повторяющегося уведомления через 10 минут. Это не ждет 10 минут - срабатывает сразу в следующую минуту.
NSDate *theDate = [NSDate dateWithTimeIntervalSinceNow:60*10];
NSDateComponents *dateForSchedule = [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] components:NSCalendarUnitMinute|NSCalendarUnitHour|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:theDate];
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.body = "Your notification is here.";
content.sound = [UNNotificationSound defaultSound];
content.categoryIdentifier = CALL_NOTIFICATION_CATEGORY;
NSDateComponents* date = [[NSDateComponents alloc] init];
if ([self.selectedFrequecy isEqualToString:HOURLY]) {
date.minute = dateForSchedule.minute;
} else if ([self.selectedFrequecy isEqualToString:DAILY]) {
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute;
} else if ([self.selectedFrequecy isEqualToString:WEEKLY]) {
date.weekday = dateForSchedule.weekday;
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute
} else if ([self.selectedFrequecy isEqualToString:MONTHLY]) {
date.day = dateForSchedule.day;
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute;
} else if ([self.selectedFrequecy isEqualToString:YEARLY] || [self.selectedFrequecy isEqualToString:ONCE]) {
date.month = dateForSchedule.month;
date.day = dateForSchedule.day;
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute;
}
UNCalendarNotificationTrigger* trigger;
if ([_selectedFrequecy isEqualToString:ONCE]) {
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:date repeats:NO];
} else {
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:date repeats:YES];
}
// Create the request object.
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:self.callSchedule.id content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error)
{
if (error != nil) {
NSLog(@"%@", error.localizedDescription)
}
}];
Вот еще один блок кода для повторяющегося уведомления, которое будет срабатывать ежедневно через 3 дня.
NSDate *theDate = [NSDate dateWithTimeIntervalSinceNow:60*60*24*3];
NSDateComponents *dateForSchedule = [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] components:NSCalendarUnitMinute|NSCalendarUnitHour|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:theDate];
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.body = "Your notification is here.";
content.sound = [UNNotificationSound defaultSound];
content.categoryIdentifier = CALL_NOTIFICATION_CATEGORY;
NSDateComponents* date = [[NSDateComponents alloc] init];
if ([self.selectedFrequecy isEqualToString:HOURLY]) {
date.minute = dateForSchedule.minute;
} else if ([self.selectedFrequecy isEqualToString:DAILY]) {
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute;
} else if ([self.selectedFrequecy isEqualToString:WEEKLY]) {
date.weekday = dateForSchedule.weekday;
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute
} else if ([self.selectedFrequecy isEqualToString:MONTHLY]) {
date.day = dateForSchedule.day;
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute;
} else if ([self.selectedFrequecy isEqualToString:YEARLY] || [self.selectedFrequecy isEqualToString:ONCE]) {
date.month = dateForSchedule.month;
date.day = dateForSchedule.day;
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute;
}
UNCalendarNotificationTrigger* trigger;
if ([_selectedFrequecy isEqualToString:ONCE]) {
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:date repeats:NO];
} else {
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:date repeats:YES];
}
// Create the request object.
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:self.callSchedule.id content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error)
{
if (error != nil) {
NSLog(@"%@", error.localizedDescription)
}
}];
Это также не ждет 3 дня, но срабатывает сразу на следующий день.
Основная проблема в обоих случаях заключается в том, что он игнорирует время, до которого он должен ждать, чтобы начать запуск уведомления. Если кто-то понял проблему, вы потратите время на то, чтобы понять, в чем дело, или если это возможно. Я буду очень благодарен.
1 ответ
В AppDelegate
получить разрешение didfinishlauchingwithoption
if( SYSTEM_VERSION_LESS_THAN( @"10.0" ) )
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if( !error )
{
[[UIApplication sharedApplication] registerForRemoteNotifications]; // required to get the app to do anything at all about push notifications
NSLog( @"Push registration success." );
}
else
{
NSLog( @"Push registration FAILED" );
NSLog( @"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription );
NSLog( @"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
}
}];
}
В ViewController
- Реализация делегата здесь -
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSDate *theDate = [NSDate dateWithTimeIntervalSinceNow:60*1];
NSDateComponents *dateForSchedule = [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] components:NSCalendarUnitMinute|NSCalendarUnitHour|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:theDate];
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.body = @"Your notification is here.";
content.sound = [UNNotificationSound defaultSound];
content.categoryIdentifier = CALL_NOTIFICATION_CATEGORY;
NSDateComponents* date = [[NSDateComponents alloc] init];
date.month = dateForSchedule.month;
date.day = dateForSchedule.day;
date.hour = dateForSchedule.hour;
date.minute = dateForSchedule.minute;
UNCalendarNotificationTrigger* trigger;
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:date repeats:NO];
UNUserNotificationCenter *centre = [UNUserNotificationCenter currentNotificationCenter];
centre.delegate = self;
// Create the request object.
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:self.callSchedule.id content:content trigger:trigger];
[centre addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error)
{
if (error != nil) {
NSLog(@"%@", error.localizedDescription);
}
}];
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
//Called when a notification is delivered to a foreground app.
NSLog(@"Userinfo %@",notification.request.content.userInfo);
completionHandler(UNNotificationPresentationOptionAlert);
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler{
//Called to let your app know which action was selected by the user for a given notification.
NSLog(@"Userinfo %@",response.notification.request.content.userInfo);
}
Я могу получить уведомление в нужное время. Я взял весь код из вашего фрагмента кода с небольшими изменениями только для запуска кода. Вы можете увидеть, если вы найдете что-то другое.
Надеюсь, это предложение поможет вам!