Beacon only one local notification a day - ios

In my case, I wish the notification to appear only once per day.
This is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
/*
* BeaconManager setup.
*/
self.beaconManager = [[ESTBeaconManager alloc] init];
self.beaconManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"xxxalotofnumbersxxx"];
self.beaconRegion = [[ESTBeaconRegion alloc] initWithProximityUUID: uuid
major: 41270
minor: 64913
identifier: #"RegionIdentifier"];
[self.beaconManager startMonitoringForRegion:self.beaconRegion];
}
- (void)beaconManager:(ESTBeaconManager *)manager didEnterRegion:(ESTBeaconRegion *)region
{
UILocalNotification *notification = [UILocalNotification new];
notification.alertBody = #"Test";
notification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
I can try to manage it well by inserting immediately after the start?
if(notification.applicationIconBadgeNumber = 1;)
[self.beaconManager stopMonitoringForRegion:self.beaconRegion];
is there any other better solution to handle it? Thank you

Check how many local notification have been scheduled with [[UIApplication sharedApplication] scheduledLocalNotifications]; which returns a array of UILocalNotifcations. Then loop through all the UILocalNotification and check to see when it will be shown with its fireDate or userInfo.
Use repeatInterval property in UILocalNotifcation to keep track of your daily notifications raither then always creating a new notification.
if (![self isScheduledToday:[UIApplication sharedApplication].scheduledLocalNotifications]) {
// add new notifcation as its not scheduled and set repeatMode to NSDayCalendarUnit;
}
/**
* returns if there a schedule for today
*/
- (BOOL)isScheduledToday:(NSArray *)notifications {
for (UILocalNotification *notification in notifications) {
if ([self isSameDay:notification.fireDate]) {
NSLog(#"Notifcation for today: %#", notification);
return YES;
}
}
return NO;
}
/**
* checks if date matches today by comparing year, month and day
*/
- (BOOL)isSameDay:(NSDate *)anotherDate {
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone defaultTimeZone];
NSDateComponents *components1 = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
NSDateComponents *components2 = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:anotherDate];
return (components1.year == components2.year &&
components1.month == components2.month &&
components1.day == components2.day);
}

Related

why I'm not receiving the local notification. when I'm setting reminder for a day in Week in objective c

I'm developing an application where I need to set the reminder for a particular day. I'm Using Local notification and finding the date of selected Day of current week.
this is my code:
In viewController.m
NSArray* components12 = [self.LblTime.text componentsSeparatedByString:#":"];
NSString *Hours = [components12 objectAtIndex:0];
NSString *Minutes =[components12 objectAtIndex:1];
NSDate *currentDate = [NSDate date];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorianCalendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
NSDateComponents *components = [gregorianCalendar components:(NSYearCalendarUnit| NSMonthCalendarUnit
| NSDayCalendarUnit| NSWeekdayCalendarUnit|NSWeekCalendarUnit) fromDate:currentDate];
NSLog(#"Current week day number %ld",(long)[components weekday]);
NSLog(#"Current week number %ld",(long)[components week]);
NSLog(#"Current month's day %ld",(long)[components day]);
NSLog(#"Current month %ld",(long)[components month]);
NSLog(#"Current year %ld",(long)[components year]);
NSDateComponents *dt=[[NSDateComponents alloc]init];
//Passing the Time (hours and minutes ) and Selected day with date
[dt setHour: [Hours integerValue]];
[dt setMinute:[Minutes integerValue]];
[dt setSecond:0];
[dt setWeek:[components week]];
[dt setWeekday:selecteddayValue];/// set the week Selected ay from picker
[dt setMonth:[components month]];
[dt setYear:[components year]];
NSDate *Date=[gregorianCalendar dateFromComponents:dt];// get the date of selected day of week
NSLog(#"Sunday date :%#",Date);
//Adding the reminder through Local notifiction
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate =Date;
localNotification.alertBody = #"Ready For Next Workout!";
localNotification.soundName = UILocalNotificationDefaultSoundName;
// localNotification.applicationIconBadgeNumber = 1; // increment
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:#"Object 1", #"Key 1", #"Object 2", #"Key 2", nil];
localNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[self showAlert:#"Reminder set Successfully"];
in appDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
// Handle launching from a notification
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
{
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
Now I'm not receiving the notification. Anyone please help for this.that would be very apperitiate.
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0)
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}

App Delegate's application:didReceiveLocalNotification: not called

In my app delegate the method - (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification is never called.
This is how I create the notification:
UILocalNotification *notification = [[UILocalNotification alloc] init];
// set UUID, which we will store in userDefaults for later
NSMutableDictionary *myUserInfo = [[NSMutableDictionary alloc] init];
NSString *uuid = [[NSProcessInfo processInfo] globallyUniqueString];
[myUserInfo setValue:uuid forKey:KEY_UUID];
[myUserInfo setValue:#"month" forKey:KEY_UNIT];
[myUserInfo setObject:#YES forKey:KEY_RESCHEDULE];
NSInteger row = [_wurmProphylaxePickerView selectedRowInComponent:0];
switch (row) {
case 0:
[myUserInfo setValue:#2 forKey:KEY_FREQUENCY];
break;
case 1:
[myUserInfo setValue:#4 forKey:KEY_FREQUENCY];
break;
case 2:
[myUserInfo setValue:#6 forKey:KEY_FREQUENCY];
break;
default:
[myUserInfo setValue:#4 forKey:KEY_FREQUENCY];
break;
}
notification.userInfo = myUserInfo;
// calculate date for next notification, depends on the user's selection
NSDate *today = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *myComps = [[NSDateComponents alloc] init];
[myComps setMinute:1];
notification.fireDate = [calendar dateByAddingComponents:myComps toDate:today options:0];
notification.timeZone = [NSTimeZone localTimeZone];
notification.alertBody = #"My alertBody";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
And this is in my app delegates, but is never called:
- (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification
{
NSDictionary *userInfo = notification.userInfo;
BOOL repeat = [[userInfo objectForKey:KEY_RESCHEDULE] boolValue];
if (repeat)
{
NSInteger frequency = (NSInteger)[userInfo objectForKey:KEY_FREQUENCY];
NSString *unit = (NSString *)[userInfo objectForKey:KEY_UNIT];
NSString *uuid = (NSString *)[userInfo objectForKey:KEY_UUID];
// calculate date for next notification
NSDate *today = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *myComps = [[NSDateComponents alloc] init];
if ([unit isEqualToString:#"month"]) {
//[myComps setMonth:frequency];
[myComps setMinute:frequency];
} else {
}
// create new notification
UILocalNotification *newNotification = [[UILocalNotification alloc] init];
newNotification.fireDate = [calendar dateByAddingComponents:myComps toDate:today options:0];
newNotification.timeZone = [NSTimeZone localTimeZone];
newNotification.alertAction = notification.alertAction;
newNotification.alertBody = notification.alertBody;
newNotification.userInfo = notification.userInfo;
// schedule it
[[UIApplication sharedApplication] scheduleLocalNotification:newNotification];
}
}
tested on iOS 8, not sure about iOS 7...
If the app is not active when the notification fires, you would handle this in didFinishLaunchingWithOptions as illustrated by this example from the Handling Local and Remote Notifications section of the Local and Push Notifications Programming Guide:
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSString *itemName = [localNotif.userInfo objectForKey:ToDoItemKey];
[viewController displayItem:itemName]; // custom method
app.applicationIconBadgeNumber = localNotif.applicationIconBadgeNumber-1;
}
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
The didReceiveLocalNotification is called if the app was active when the notification fired.

How to remove already scheduled LocalNotifications in an app? [duplicate]

This question already has an answer here:
IOS Cancelling Local Notifications
(1 answer)
Closed 8 years ago.
I am using Local Notifications. I want to delete already scheduled notifications.I don't know where to write the code.Here is my code ..
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
// Get the current date
NSDate *pickerDate = self.selectedDate;
NSLog(#" self.selectedDate %#", self.selectedDate);
// Break the date up into components
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit )
fromDate:pickerDate];
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit )
fromDate:pickerDate];
// Set up the fire time
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
// Notification will fire in one minute
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
NSLog(#"itemDate %#",itemDate);
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = itemDate;
NSLog(#"itemDate %#", localNotif.fireDate);
localNotif.timeZone = [NSTimeZone defaultTimeZone];
// Notification details
localNotif.alertBody = [_titleTextFieldObj text];
// Set the action button
localNotif.alertAction = #"View";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber =[[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
NSLog(#" localNotif.applicationIconBadgeNumber ++ %ld", (long)localNotif.applicationIconBadgeNumber );
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:[_titleTextFieldObj text] forKey:#"someKey"];
localNotif.userInfo = infoDict;
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
//UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];
NSLog(#"notif %#",notificationArray);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
Here I'm writing the removing of notification....
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
application.applicationIconBadgeNumber=1;
UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++)
{
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
NSDictionary *userInfoCurrent = oneEvent.userInfo;
NSLog(#"userInfoCurrent %#",userInfoCurrent);
NSString *uid=[NSString stringWithFormat:#"%#",[userInfoCurrent valueForKey:#"uid"]];
NSLog(#"uid %#",uid);
if ([uid isEqualToString:[notification.userInfo objectForKey:#"someKey"]])
{
//Cancelling local notification
[app cancelLocalNotification:oneEvent];
break;
}
}
if (notification) {
NSLog(#"notify %#",notification);
NSString *custom=[notification.userInfo objectForKey:#"someKey"];
NSLog(#"custom %#",custom);
NSString *newString = [custom stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"newString %#",newString);
NSLog(#"custmky%#",notification.description);
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Message" message:newString delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
alert.delegate=self;
[alert show];
}
}
I am new to UILocalNotifications and Objective-c. Can anyone please help me ....
You can cancel a UILocationNotification either by comparing fire dates to already scheduled UILocalNotifications or using its body.
An example of canceling by fire date:
UIApplication *application = [UIApplication sharedApplication];
NSDate *dateToCancel = nil; // Set this to the date you want to cancel
for (UILocalNotification *notification in [application scheduledLocalNotifications])
{
if (notification.fireDate == dateToCancel)
{
[application cancelLocalNotification:notification];
}
}
Now if you have a notification pointer you can just call the cancel local notification without needing to loop through already scheduled notifications. If you want you can also add an Id tag to the notification through key-object methods.
No matter in which class that code will lay, it's anywhere using UIApplication singleton...
You can cancel all notification using:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
If you want to remove a particular notification, you can use userinfo of notification object, when you create a local notification add a unique ID to that. Later you can use that ID for removing local notification.
For that you can use the following code:
NSString *notificationId = #"id_to_cancel";
UILocalNotification *notification = nil;
for(UILocalNotification *notify in [[UIApplication sharedApplication] scheduledLocalNotifications])
{
if([notify.userInfo objectForKey:#"ID"] isEqualToString:notificationId ])
{
notification = notify;
break;
}
}
[[UIApplication sharedApplication] cancelLocalNotification:notification];

Cancelling of UILOcalNotifications [duplicate]

This question already has answers here:
Removing UILocalNotification from notification tray programmatically
(7 answers)
Closed 8 years ago.
I am using UILocalNotifications in my app.Now my requirement is the local notification should be cancelled after it’s scheduled.
Here my Code…
-(void)LocalNotificationMethod{
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
// Get the current date
NSDate *pickerDate = self.selectedDate;
NSLog(#" self.selectedDate %#", self.selectedDate);
// Break the date up into components
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit )
fromDate:pickerDate];
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit )
fromDate:pickerDate];
// Set up the fire time
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
// Notification will fire in one minute
[dateComps setMinute:[timeComponents minute]];
[dateComps setSecond:[timeComponents second]];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
NSLog(#"itemDate %#",itemDate);
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = itemDate;
NSLog(#"itemDate %#", localNotif.fireDate);
localNotif.timeZone = [NSTimeZone defaultTimeZone];
// Notification details
localNotif.alertBody = [_titleTextFieldObj text];
// Set the action button
localNotif.alertAction = #"View";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber =[[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
NSLog(#" localNotif.applicationIconBadgeNumber ++ %ld", (long)localNotif.applicationIconBadgeNumber );
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:[_titleTextFieldObj text] forKey:#"someKey"];
localNotif.userInfo = infoDict;
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
//UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];
NSLog(#"notif %#",notificationArray);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
**In Appdelegate.m i wrote the code like…**
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
application.applicationIconBadgeNumber=1;
if (notification) {
NSLog(#"notify %#",notification);
NSString *custom=[notification.userInfo objectForKey:#"someKey"];
NSLog(#"custom %#",custom);
NSString *newString = [custom stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"newString %#",newString);
NSLog(#"custmky%#",notification.description);
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Message" message:newString delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
alert.delegate=self;
[alert show];
}
//UIApplication *application = [UIApplication sharedApplication];
NSString *notificationId = #"id_to_cancel";
//UILocalNotification *notification = nil;
for(UILocalNotification *notify in [[UIApplication sharedApplication] scheduledLocalNotifications])
{
if([[notify.userInfo objectForKey:#"someKey"] isEqualToString:notificationId ])
{
notification = notify;
break;
}
}
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
but it is not going into the loop …
I am new to this concept.Can anyone please help me to resolve this….
Thanks in advance.
You want to cancel a scheduled notification based on receiving another notification, if it is the case you need to put the loop before showing the Alert else your loop will never be executed. or in case you need to cancel/or not notification based button that will be taped in your AlertView you can put that code in your alertView delegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex==0) {
for(UILocalNotification *notify in [[UIApplication sharedApplication] scheduledLocalNotifications]){
if([[notify.userInfo objectForKey:#"someKey"] isEqualToString:#"someValue"]) {
[[UIApplication sharedApplication] cancelLocalNotification:notify];
break;
}
}
}
By Default all UILocalNotification is OneTime so it cancel automatically after its fireDate
And looks like you are trying to get same UILocalNotification.
Please try putting same code at different place you will get all your Scheduled Notifications Or try to get all Scheduled Notifications before fireDate.

iOS UILocalNotification set to fire once every day, once every two days, and only on Sundays

I'm trying to use a settings bundle to schedule a UILocalNotification. In settings, you can choose if you want the notifications to come daily (1/day), 1 every 2 days, only on Sundays or never.
Here is the code I used (this is all in 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;
}
Is the code correct for launching the notifications as I've stated?
If not, what's the problem with it? Thanks!
It seems you are scheduling notifications whenever the user changes preferences. However, you never unschedule previously scheduled notifications, which is why you are observing bursts of notifications at times that will correspond exactly to the times you repeatedly changed settings a day or two days ago.
The notifications you schedule are different objects than the set of notifications that you intend to modify. Unfortunately, UILocalNotifications have no identifier tokens.
However, you can unschedule all previous notifications whenever you receive a defaultsChanged: message with [[UIApplication sharedApplication] cancelAllLocalNotifications]; before you reschedule. This will solve your problem.
Also have a close look at this solution which suggests to cancel and reschedule notifications even upon launch to avoid bursts or duplicate notifications when a user re-installs your app.
I have two ideas,
First: what's the value of dictToday ?
NSDictionary *dictToday= [self getDataFromdate : [compoNents day] month:[compoNents month]];
[dictToday objectForKey:#"saint_description"]
If this value is nil, your notification will not pop.
Second: Check your time zone and the time zone returned from:
[NSTimeZone defaultTimeZone]
You could be on a +3 time zone and setting your localnotification to fire on a negative time zone and that is never going to happen.

Resources