I don't see support for scheduling such kind of notification i.e. that repeats only when a specific time passes. The problem is that the schedule fires immediately without waiting for the exact time although repeats correctly.
e.g. here is the code for scheduling a repeating notification after 10 minutes. This doesn't wait for the 10 minutes - fires immediately in the next minute from now.
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)
}
}];
here is another block of code for a repeating notification that will fire daily after 3 days.
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)
}
}];
This also doesn't wait for the 3 days but fires immediately on the next day.
The main problem in both is that it ignores the time till which it should wait to start firing the notification. If anybody has understood the problem, will you take some time to figure out what's wrong or if it's possible. I will be really thankful.
In
AppDelegate
take permissiondidfinishlauchingwithoption
In
ViewController
- Implement delegate here -I am able to get the notification at correct time. I have taken all code from your code snippet with very small change just to run the code. You can see if you find anything different.
Hope this suggestion helps you !