如何在iOS(ObjC)中安排每日本地推送通知?

无法以正确的方式安排每日本地PushNotification 。 我想在上午9:00只显示一个每日本地推送通知,并计算今天的任务。

我的代码在didFinishLaunchingWithOptions只执行一次,如:

 - (void)scheduleLocalNotification { self.localNotification = [UILocalNotification new]; unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:unitFlags fromDate:[NSDate date]]; components.hour = 9; components.minute = 0; components.second = 0; NSDate *fireTime = [calendar dateFromComponents:components]; _localNotification.fireDate = fireTime; _localNotification.alertBody = [NSString stringWithFormat:@"Hi, <username>. You have %ld tasks for today", (long)_todayTasks]; _localNotification.repeatInterval = NSCalendarUnitDay; _localNotification.soundName = @"alarm.wav"; _localNotification.timeZone = [NSTimeZone localTimeZone]; [[UIApplication sharedApplication] scheduleLocalNotification:_localNotification]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"HH:mm"]; NotificationManagerLog(@"schedule local notification at %@", [dateFormatter stringFromDate:fireTime]); } 

看起来我错过了一些东西,因为它真的是在9:00触发的,但是在_todayTasks有错误的数据,也可以用其他_todayTasks值随机触发,随机重复几次。

一步步:

  1. 注册通知:

     - (void)prepareLocalNotification { if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } else { UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes]; } } 
  2. 如果用户允许本地通知,则创build通知(例如,每天下午3点):

     - (void)createDailyBasisNotification { [[UIApplication sharedApplication] cancelAllLocalNotifications]; UILocalNotification *next3pm = [self notificationForTime:15 withMessage:<NotificationMessage3PM> soundName:UILocalNotificationDefaultSoundName]; [[UIApplication sharedApplication] scheduleLocalNotification:next3pm]; } - (UILocalNotification *)notificationForTime:(NSInteger)time withMessage:(NSString *)message soundName:(NSString *)soundName { UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.alertBody = message; localNotification.repeatInterval = NSDayCalendarUnit; localNotification.timeZone = [NSTimeZone localTimeZone]; localNotification.soundName = soundName; NSDate *date = [NSDate date]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *dateComponents = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date]; [dateComponents setHour:time]; NSDate *next = [calendar dateFromComponents:dateComponents]; if ([next timeIntervalSinceNow] < 0) { next = [next dateByAddingTimeInterval:60*60*24]; } localNotification.fireDate = next; return localNotification; } 

另外不要忘记调用[[UIApplication sharedApplication] cancelAllLocalNotifications]; – 这将清理所有的通知,你会删除所有的random通知

无法看到你正在定义_todayTasks 。 您的代码触发一般的通知应该工作。 就像你说的那样

也许_todayTasks尚未初始化(在启动时)? 你使用NSUserDefaults吗?

另一个问题可能是,你还没有清除你的旧通知,这是由多次启动计划,因此数据是错误的?

你可以试试NSLog打印数据,看看里面有什么。

我在调用“ applicationWillResignActive ”方法时安排通知。 此外,我清除所有其他通知时,应用程序再次启动(“ applicationDidBecomeActive ”)这样(不幸在迅速):

 // Clear all Notifications let notifications = UIApplication.sharedApplication().scheduledLocalNotifications! if notifications.count > 0 { print("reset Notifications.") UIApplication.sharedApplication().cancelAllLocalNotifications() } 
 NSString *strCurrentDate = [dateformat stringFromDate:[NSDate date]]; if ([strCurrentDate isEqualToString:[AppData getAppData].strLastDate]) { [[AppData getAppData] setIsDoneLN:YES]; } else { [[AppData getAppData] setIsDoneLN:NO]; } if (![AppData getAppData].isDoneLN) { [self callLN]; } -(void)callLN { // your notification code here NSDateFormatter *dateformat; if (!dateformat) { dateformat = [[NSDateFormatter alloc] init]; } [dateformat setDateFormat:@"yyyy-MM-dd"]; [[AppData getAppData] setStrLastDate:[dateformat stringFromDate:[NSDate date]]]; } //NOTE:[AppData getAppData] is a singleton class that return NSUserDefaults value. you can use normal NSUserDefaults to save and retrive the values instead of using [AppData getAppData].