Как запланировать уведомление, которое будет повторяться с определенной частотой по истечении определенного времени

Я не вижу поддержки для планирования такого рода уведомлений, т.е. оно повторяется только по прошествии определенного времени. Проблема в том, что расписание срабатывает сразу, не дожидаясь точного времени, хотя повторяется правильно.

например, вот код для планирования повторяющегося уведомления через 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);

}

Я могу получить уведомление в нужное время. Я взял весь код из вашего фрагмента кода с небольшими изменениями только для запуска кода. Вы можете увидеть, если вы найдете что-то другое.

Надеюсь, это предложение поможет вам!

Другие вопросы по тегам