如何安排在特定时间过去后将以一定频率重复的通知

时间:2018-08-21 05:44:00

标签: ios swift3 unusernotificationcenter usernotifications unusernotification

我看不到对安排此类通知的支持,即仅在特定时间过去时才会重复。问题在于,尽管重复正确,但计划表立即启动,而无需等待确切的时间。

例如这是用于安排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 个答案:

答案 0 :(得分:0)

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);

}

我能够在正确的时间收到通知。我已经从您的代码段中提取了所有代码,只做了很小的更改就可以运行代码。您可以查看是否发现任何不同之处。

希望这个建议对您有帮助!