我试图使用设置包来安排UILocalNotification.在设置中,您可以选择是否要每天通知(每天1天),每2天1次,仅限星期日或从不.
这是我使用的代码(这一切都在AppDelegate.m中):
-(void)defaultsChanged:(NSNotification *)notification { [[UIApplication sharedApplication] cancelAllLocalNotifications]; [[NSUserDefaults standardUserDefaults]synchronize]; NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:@"multi_preference"]; NSLog(@"%@",testValue); NSDate *today = [NSDate date]; NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComponents* compoNents = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:today]; // Get necessary date components [compoNents month];[compoNents day]; NSDictionary *dictToday= [self getDataFromdate : [compoNents day] month:[compoNents month]]; if ([testValue isEqualToString:@"one"]){ UILocalNotification* localNotification = [[UILocalNotification alloc] init]; localNotification.fireDate = [[NSDate date]dateByAddingTimeInterval:20]; localNotification.alertAction = @"View"; localNotification.alertBody = [dictToday objectForKey:@"saint_description"]; localNotification.repeatInterval = NSDayCalendarUnit; localNotification.timeZone = [NSTimeZone defaultTimeZone]; localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self]; } if (testValue==Nil){ UILocalNotification* localNotification = [[UILocalNotification alloc] init]; localNotification.fireDate = [[NSDate date]dateByAddingTimeInterval:20]; localNotification.alertAction = @"View"; localNotification.alertBody = [dictToday objectForKey:@"saint_description"]; localNotification.repeatInterval = NSDayCalendarUnit; localNotification.timeZone = [NSTimeZone defaultTimeZone]; localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self]; } if ([testValue isEqualToString:@"two"]){ UILocalNotification* localNotification = [[UILocalNotification alloc] init]; localNotification.fireDate = [[NSDate date]dateByAddingTimeInterval:86401]; localNotification.alertAction = @"View"; localNotification.alertBody = [dictToday objectForKey:@"saint_description"]; localNotification.repeatInterval = NSDayCalendarUnit; localNotification.timeZone = [NSTimeZone defaultTimeZone]; localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self]; } if ([testValue isEqualToString:@"three"]){ NSDate *today2 = [[NSDate alloc] init]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; // Get the weekday component of the current date NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit fromDate:today2]; /* Create a date components to represent the number of days to subtract from the current date. The weekday value for Sunday in the Gregorian calendar is 1,so subtract 1 from the number of days to subtract from the date in question. (If today is Sunday,subtract 0 days.) */ NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init]; [componentsToSubtract setDay: 0 - ([weekdayComponents weekday] - 1)]; NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract toDate:today2 options:0]; /* Optional step: beginningOfWeek now has the same hour,minute,and second as the original date (today). To normalize to midnight,extract the year,month,and day components and create a new date from those components. */ NSDateComponents *components = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate: beginningOfWeek]; beginningOfWeek = [gregorian dateFromComponents:components]; UILocalNotification* localNotification = [[UILocalNotification alloc] init]; localNotification.fireDate = beginningOfWeek; localNotification.alertAction = @"View"; localNotification.alertBody = [dictToday objectForKey:@"saint_description"]; localNotification.repeatInterval = NSWeekdayCalendarUnit; localNotification.timeZone = [NSTimeZone defaultTimeZone]; localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self]; } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(defaultsChanged:) name:NSUserDefaultsDidChangeNotification object:nil]; UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; if (locationNotification) { // Set icon badge number to zero application.applicationIconBadgeNumber = 0; } return yes; } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Today's Saint" message:notification.alertBody delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; if (notification.alertBody!=Nil) [alert show]; [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self]; // Set icon badge number to zero application.applicationIconBadgeNumber = 0; }
解决方法
您似乎在用户更改首选项时调度通知.但是,您永远不会取消调度以前安排的通知,这就是为什么您会在一段时间内观察突发的通知,这些通知的时间将完全对应于您每天或两天前反复更改设置的时间.
您计划的通知是与您要修改的通知集不同的对象.不幸的是,UILocalNotifications没有标识符令牌.
但是,您可以在收到带有[[UIApplication sharedApplication] cancelAllLocalNotifications]的defaultsChanged:消息时取消调度所有以前的通知;在你重新安排之前.这将解决您的问题.
还要仔细查看this solution,建议即使在启动时也可以取消并重新安排通知,以避免在用户重新安装应用程序时发生突发或重复通知.