每天根据数组 Objective c ios 中给定的动态时间自动触发本地通知
Trigger local notifications automatically daily on dynamic time given in arrays Objective c ios
我有一个小时数组 hoursArray
和一个分钟数组 minutesArray
我正在从系统中获取 current date
现在我有包含当前元素的数组月,这意味着如果四月有 30 天,我插入数组的 hoursArray/minutesArray 中会有 30 hours/minutes,我正在获取当前日期作为数组的索引。
我所做的是通知在当天触发,但在我每天使用应用程序之前不会在第二天触发,因为当我每天使用应用程序时,触发时间方法将在我转到后台模式时调用并且通知响铃。
现在我希望在日期更改时自动触发通知,即使我有几天不使用该应用程序,这些所有东西都应该在 appDelegate
的 didEnterBackground...
方法中
我已关注 this answer,但它每天用于同一时间但我希望每天从基于当前日期的数组索引的数组中获取不同的时间(这意味着当前日期,例如今天是 4 月 19 日索引小时和分钟数组应该是 19).
这是我的数组的样子
小时数组= [9, 10, 11, 13, 14, 11, 17, 2, 15, 5....等等]
分数组=[23,00,04,58,59,12,01,33,....等等]
方法在 appdelegate.m
中调用
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self.viewController triggerAutomaticallyDaily];
[self applicationSignificantTimeChange:application];
[self refreshAlarm];
}
里面的方法viewcontroller.m
-(void)triggerAutomaticallyDaily {
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar] ;
NSDate *now = [NSDate date];
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:now];
[components setHour:hoursArray[currentDay]]; //currentDay the todays date is 16 I am getting current date from system.
[components setMinute:minutesArray[currentDay]];
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.fireDate = [calendar dateFromComponents:components];
notification.repeatInterval = NSDayCalendarUnit;
[notification setAlertBody:@"This is your task time"];
// notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
每个午夜后时间都会发生重大变化,Appdelegate
中的方法
-(void)applicationSignificantTimeChange:(UIApplication *)application {
[self.viewController triggerAutomaticallyDaily];
}
在Appdelegate
中刷新报警方法
- (void)refreshLabel
{
//refresh the alarm on the main thread
dispatch_async(dispatch_get_main_queue(),^{
[self.viewController triggerAutomaticallyDaily];
});
// check every 10000s
[self performSelector:@selector(refreshLabel) withObject:nil afterDelay:10000];
}
看看 didEnterBackground...
当我退出我的应用程序时,通知方法只会被调用一次。是不是??以及当我一周不打开应用程序但我想收到通知时如何收到每日通知,将如何调用方法?在后台模式下每次都调用方法吗?
有什么办法可以让我安排通知,当第一个通知完成时,第二个应该被触发,如果第二个完成,那么第三个应该被触发等等,即使我没有打开后台模式一个星期的应用程序??应根据数组中给出的当前日期和时间触发通知。
更新
我什至放置了刷新功能,它每隔 10000 秒刷新一次触发器,但它不起作用。
我还添加了 significantTimechanges
,如果有午夜变化但它在这里不起作用是我定义的全部。
只需使用下面的语句而不是 NSCalendar
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.fireDate = [[NSDate date] dateByAddingTimeInterval:(hours*3600)+(Mins*60)];
//时间间隔单位应该是秒
notification.repeatInterval = NSDayCalendarUnit;
[notification setAlertBody:@"This is your task time"];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
重要说明:如果应用程序长时间处于终止状态或后台,开发人员将无法执行任何操作。所以这个做不到。
您的要求有很多问题:
1.1: 你在一项服务中有多少 days data
,for a month
、for a year
或 ?
1.2: 为什么不push
?
1.3: 为什么要每天安排 local notification
而你一次可以安排很多?
1.4: 当 app
未打开(被用户杀死)时,无法在 app
中进行更改,因此在这种情况下您无能为力。
现在来看看我们能做什么:
2.1: 考虑到您正在获取月度数据。因此,您应该通过增加 day component
并设置相应的时间 (from your arrays by day index)
,在 for loop
中一次安排所有 local notifications
。如果用户每月打开一次应用程序(90% 的可能性他会),那么你可以向服务器请求下个月的数据并执行相同的操作。
2.2: 为什么不在服务器端处理并使用 push notifications
而不是 local
。服务器人员可以为每一分钟配置一个 cron 作业,这将为用户获取所有时间和分钟,并发送 push
。
我的建议是不要使用 local
,但您可以使用 2.1
的所有最大值(一次安排所有月份的通知)。
正如其他人所说,更好的技术是一次安排所有通知。这就是我所做的。但是,系统限制为 64 个待处理的本地通知。在您的情况下,计划的通知应在 64 天内每天触发。我有一个更困难的问题,因为我需要每 15 分钟安排一次通知。因此,如果我的用户未在 16 小时内回复,他们将不会收到进一步的通知 (64/4 = 16)。另外,请注意 UILocalNotification 已弃用,因此您应该使用 UNNotificationRequest。请注意,UNCalendarNotificationTrigger 中的 identifier 对于每个请求必须是唯一的。
content.categoryIdentifier = @"com.nelsoncapes.localNotification";
NSDate *today = [NSDate date];
NSDate *fireDate = [today dateByAddingTimeInterval:interval];
// first extract the various components of the date
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger year = [calendar component:NSCalendarUnitYear fromDate:fireDate];
NSInteger month = [calendar component:NSCalendarUnitMonth fromDate:fireDate];
NSInteger day = [calendar component:NSCalendarUnitDay fromDate:fireDate];
NSInteger hour = [calendar component:NSCalendarUnitHour fromDate:fireDate];
NSInteger minute = [calendar component:NSCalendarUnitMinute fromDate:fireDate];
NSDateComponents *components = [[NSDateComponents alloc]init];
components.year = year;
components.month = month;
components.day = day;
components.hour = hour;
components.minute = minute;
…
// construct a calendarnotification trigger and add it to the system
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier: identifier content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError *error){
if(error){
NSLog(@"error on trigger notification %@", error);
}
}];
我有一个小时数组 hoursArray
和一个分钟数组 minutesArray
我正在从系统中获取 current date
现在我有包含当前元素的数组月,这意味着如果四月有 30 天,我插入数组的 hoursArray/minutesArray 中会有 30 hours/minutes,我正在获取当前日期作为数组的索引。
我所做的是通知在当天触发,但在我每天使用应用程序之前不会在第二天触发,因为当我每天使用应用程序时,触发时间方法将在我转到后台模式时调用并且通知响铃。
现在我希望在日期更改时自动触发通知,即使我有几天不使用该应用程序,这些所有东西都应该在 appDelegate
的 didEnterBackground...
方法中
我已关注 this answer,但它每天用于同一时间但我希望每天从基于当前日期的数组索引的数组中获取不同的时间(这意味着当前日期,例如今天是 4 月 19 日索引小时和分钟数组应该是 19).
这是我的数组的样子
小时数组= [9, 10, 11, 13, 14, 11, 17, 2, 15, 5....等等]
分数组=[23,00,04,58,59,12,01,33,....等等]
方法在 appdelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self.viewController triggerAutomaticallyDaily];
[self applicationSignificantTimeChange:application];
[self refreshAlarm];
}
里面的方法viewcontroller.m
-(void)triggerAutomaticallyDaily {
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar] ;
NSDate *now = [NSDate date];
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:now];
[components setHour:hoursArray[currentDay]]; //currentDay the todays date is 16 I am getting current date from system.
[components setMinute:minutesArray[currentDay]];
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.fireDate = [calendar dateFromComponents:components];
notification.repeatInterval = NSDayCalendarUnit;
[notification setAlertBody:@"This is your task time"];
// notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
每个午夜后时间都会发生重大变化,Appdelegate
-(void)applicationSignificantTimeChange:(UIApplication *)application {
[self.viewController triggerAutomaticallyDaily];
}
在Appdelegate
- (void)refreshLabel
{
//refresh the alarm on the main thread
dispatch_async(dispatch_get_main_queue(),^{
[self.viewController triggerAutomaticallyDaily];
});
// check every 10000s
[self performSelector:@selector(refreshLabel) withObject:nil afterDelay:10000];
}
看看 didEnterBackground...
当我退出我的应用程序时,通知方法只会被调用一次。是不是??以及当我一周不打开应用程序但我想收到通知时如何收到每日通知,将如何调用方法?在后台模式下每次都调用方法吗?
有什么办法可以让我安排通知,当第一个通知完成时,第二个应该被触发,如果第二个完成,那么第三个应该被触发等等,即使我没有打开后台模式一个星期的应用程序??应根据数组中给出的当前日期和时间触发通知。
更新 我什至放置了刷新功能,它每隔 10000 秒刷新一次触发器,但它不起作用。
我还添加了 significantTimechanges
,如果有午夜变化但它在这里不起作用是我定义的全部。
只需使用下面的语句而不是 NSCalendar
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.fireDate = [[NSDate date] dateByAddingTimeInterval:(hours*3600)+(Mins*60)];
//时间间隔单位应该是秒
notification.repeatInterval = NSDayCalendarUnit;
[notification setAlertBody:@"This is your task time"];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
重要说明:如果应用程序长时间处于终止状态或后台,开发人员将无法执行任何操作。所以这个做不到。
您的要求有很多问题:
1.1: 你在一项服务中有多少 days data
,for a month
、for a year
或 ?
1.2: 为什么不push
?
1.3: 为什么要每天安排 local notification
而你一次可以安排很多?
1.4: 当 app
未打开(被用户杀死)时,无法在 app
中进行更改,因此在这种情况下您无能为力。
现在来看看我们能做什么:
2.1: 考虑到您正在获取月度数据。因此,您应该通过增加 day component
并设置相应的时间 (from your arrays by day index)
,在 for loop
中一次安排所有 local notifications
。如果用户每月打开一次应用程序(90% 的可能性他会),那么你可以向服务器请求下个月的数据并执行相同的操作。
2.2: 为什么不在服务器端处理并使用 push notifications
而不是 local
。服务器人员可以为每一分钟配置一个 cron 作业,这将为用户获取所有时间和分钟,并发送 push
。
我的建议是不要使用 local
,但您可以使用 2.1
的所有最大值(一次安排所有月份的通知)。
正如其他人所说,更好的技术是一次安排所有通知。这就是我所做的。但是,系统限制为 64 个待处理的本地通知。在您的情况下,计划的通知应在 64 天内每天触发。我有一个更困难的问题,因为我需要每 15 分钟安排一次通知。因此,如果我的用户未在 16 小时内回复,他们将不会收到进一步的通知 (64/4 = 16)。另外,请注意 UILocalNotification 已弃用,因此您应该使用 UNNotificationRequest。请注意,UNCalendarNotificationTrigger 中的 identifier 对于每个请求必须是唯一的。
content.categoryIdentifier = @"com.nelsoncapes.localNotification";
NSDate *today = [NSDate date];
NSDate *fireDate = [today dateByAddingTimeInterval:interval];
// first extract the various components of the date
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger year = [calendar component:NSCalendarUnitYear fromDate:fireDate];
NSInteger month = [calendar component:NSCalendarUnitMonth fromDate:fireDate];
NSInteger day = [calendar component:NSCalendarUnitDay fromDate:fireDate];
NSInteger hour = [calendar component:NSCalendarUnitHour fromDate:fireDate];
NSInteger minute = [calendar component:NSCalendarUnitMinute fromDate:fireDate];
NSDateComponents *components = [[NSDateComponents alloc]init];
components.year = year;
components.month = month;
components.day = day;
components.hour = hour;
components.minute = minute;
…
// construct a calendarnotification trigger and add it to the system
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier: identifier content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError *error){
if(error){
NSLog(@"error on trigger notification %@", error);
}
}];