I'm currently trying to cancel specific UILocalNotifications associated with objects in my data model. To do this, each data object has a unique identifier, which is an NSUUID.
Create UILocalNotification:
/* Set UILocalNotification */
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = date;
localNotification.alertBody = self.mytextfield.text;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
NSLog(#"making a notification: %#",[r.uniqueId UUIDString]);
[localNotification.userInfo setValue:[r.uniqueId UUIDString] forKey:#"uid"];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
Yet when I go to delete the notification and print out each notifications contents, the alertbody of the notifications are printed correctly but the unique identifier is somehow lost. What's wrong with this implementation?
Cancel UILocalNotification:
Obj *r = (Obj *)[self.objects[indexPath.section] objectAtIndex:indexPath.row];
/* Cancel UILocalNotification */
NSArray *scheduleReminders = [[UIApplication sharedApplication] scheduledLocalNotifications];
NSLog(#"scheduled.count: %i",(int)scheduleReminders.count); // Correctly prints 3
for (int i = 0; i < scheduleReminders.count; i++)
{
UILocalNotification *notification = scheduleReminders[i];
NSDictionary *userInfoCurrent = notification.userInfo;
NSLog(#"searching through reminders: %i %# %# %#",(int)i,[userInfoCurrent objectForKey:#"uid"], notification.alertBody); // Alert body prints correctly
if ([[userInfoCurrent valueForKey:#"uid"] isEqualToString:[r.uniqueId UUIDString]])
{
NSLog(#"found it");
//Cancelling local notification
[[UIApplication sharedApplication] cancelLocalNotification:notification];
break;
}
}
The problem is that userInfo is "nil" by default. You should allocate your own NSDictionary, set uid and then set this dictionary to localNotification.userInfo.
Related
I need to clear already displayed local notification from Notification Centre programmatically. Following this link I implemented suggested solution, but the problem is that eventArray from this example always has 0 elements. When I swipe down to display Notification Centre I see 4 notifications that I've created previously. So in this case I expect this array to have 4 elements, but it has 0. Any idea why is this so? I've tried on iOS 8.3 and 9.2.1 and array is 0 on both of them.
iOS has 2 ways of presenting local notifications:
From Notification Center:
You can't swipe away notification from left to right.
You can swipe notification from right to left (deleting single notification from the list).
You can click on the notification, after which your app will start and notification will be removed from Notification Center (handled by iOS system)
From Lock screen:
Available only if you enable this setting from iPhone/iPad settings: http://www.imore.com/how-disable-notification-center-lock-screen-your-iphone-and-ipad
You can swipe notification from left to right (your app will be started, handled by iOS). In this case notification from Notification Center is not deleted (iOS doesn't delete it, and doesn't allow deleting a single notification from code after notification is already presented to the user in Notification Center).
You can swipe notification from right to left (deleting single notification from the list, handled by iOS. Notification Center notification is also deleted, handled by iOS).
You can't click on the notification.
EDIT:
Here is code sample how I did it:
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = #"1";
localNotification.alertTitle = #"1";
localNotification.userInfo = uniqueDictIdentifier1;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
UILocalNotification *localNotification2 = [[UILocalNotification alloc] init];
localNotification2.alertBody = #"2";
localNotification2.alertTitle = #"2";
localNotification2.userInfo = uniqueDictIdentifier2;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification2];
....
//2 more notifications are created like this
And then there is code for filtering all notifications:
NSArray *eventArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++) {
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
NSDictionary *userInfoCurrent = oneEvent.userInfo;
if ([userInfoCurrent isEqualToDictionary:uniqueDictIdentifier1]) {
[[UIApplication sharedApplication] cancelLocalNotification:oneEvent];
break;
}
}
For saving a notification for a unique id
NSDictionary * infoDict = #{ #"alarmUiqueId" : uID,
};
NSLog(#"%#",infoDict);
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSCalendarUnitSecond
fromDate:fireDate];
fireDate = [fireDate dateByAddingTimeInterval:-comp.second];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = fireDate;
localNotif.timeZone = [NSTimeZone localTimeZone];
localNotif.alertBody = desString;
localNotif.userInfo = infoDict;
localNotif.repeatInterval = NSCalendarUnitDay;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif]
and for delete a paritcular notification write this code.
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for(UILocalNotification *notification in notificationArray)
{
NSLog(#"%#",[notification.userInfo valueForKey:#"alarmUiqueId"]);
if ([[notification.userInfo valueForKey:#"alarmUiqueId"] isEqualToNumber: health.uniqueId])
{
[[UIApplication sharedApplication] cancelLocalNotification:notification] ;
}
}
My understanding is below:
You can not get the information of already notified LocalNotification with scheduledNotifications.
My resolution is that just keep UILocalNotification instance in your singleton object in your application, and call cancelLocalNotification with the instance when you want to delete from Notification Center.
Is this could be your help ?
I'm using a UILocalNotification object to give notification to my application. Currently each time an event is generated i popup a notification.
notification.alertBody=#"Event Occurs 2";
notification.alertAction=#"Open";
[[UIApplication sharedApplication]presentLocalNotificationNow:notification];
But, since the events keep on happening, each time a new notification is generated.
Is there a way to update a notification, if it is already present and create a new notification if not present.
You can't update an already scheduled Local Notication. You can however, cancel it and reschedule a new one.
Cancel your local notification:
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;
NSString *uid=[NSString stringWithFormat:#"%#",[userInfoCurrent valueForKey:#"uid"]];
if ([uid isEqualToString:uidtodelete])
{
//Cancelling the specific local notification
[app cancelLocalNotification:oneEvent];
//Schedule your new "updated" local notification here.
break;
}
}
This will loop through all scheduled local notifications and delete the local notification you want deleted. Note, you'll need to set a unique property to each notification to distinguish between others (in the example above, it is assumed userInfo contains a unique "uid").
Thanks to KingofBliss for code above on how to delete specific local notifications.
It's not possible to update the notification but if you attach a dictionary with a key to the alert:
UILocalNotification *notification = [[UILocalNotification alloc] init];
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[userInfo setObject:alarmID forKey:#"AlarmKey"];
// Set some extra info to your alarm
notification.userInfo = userInfo;
Then you can retrieve the local notification, cancel it and make a new one with updated content.
+ (UILocalNotification *)existingNotificationWithAlarmID:(NSString *)alarmID
{
for (UILocalNotification *notification in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
if ([[notification.userInfo objectForKey:#"AlarmKey"] isEqualToString:alarmID]) {
return notification;
}
}
return nil;
}
You cancel the notification like this:
- (void)cleanUpLocalNotificationWithAlarmID:(NSString *)alarmID
{
UILocalNotification *notification = [self existingNotificationWithAlarmID:alarmID];
if (notification) {
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
No, there is no way to modify a local notification that has been scheduled. You'll have to cancel the notification and schedule it again.
I have a multiple local notification which repeat every minutes.when local notification are arrive then i update the database.It's Work fine. But when we set multiple notification then It's fire time is Same.so both local notification simultaneously execute at same time.*This situation into my database update is not work properly.means first value reference data are updated *
//below set notification.
AlarmNotification = [[UILocalNotification alloc]init];
// AlarmNotification.fireDate = SetAlarmTime;
AlarmNotification.fireDate = AddMinutes;
AlarmNotification.repeatInterval = NSMinuteCalendarUnit;
AlarmNotification.alertBody =cloclListInsert.labelText;
AlarmNotification.timeZone = [NSTimeZone defaultTimeZone];
AlarmNotification.soundName =cloclListInsert.SelctAlaemToneDbStr;
NSMutableDictionary *userDict = [[NSMutableDictionary alloc] init];
NSString *ClockIDStr = [NSString stringWithFormat:#"%i",cloclListInsert.ClockIDvalue];
[userDict setObject:ClockIDStr forKey:#"ClockID"];
AlarmNotification.userInfo = userDict;
[[UIApplication sharedApplication]scheduleLocalNotification:AlarmNotification];
delegate method in App Delegate
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"notification.userInfo : %#",notification.userInfo);
NSString *SelectID= [notification.userInfo objectForKey:#"ClockID"];
NSLog(#"SelectID is : %#",SelectID);
NSLog(#"notification.userInfo : %#",notification.userInfo);
NotificationId = [SelectID integerValue];
NSLog(#"NotificationId is : %i",NotificationId);
clocklistobj.ClockIDvalue = NotificationId;
if ([sqldbobj getNotificationClockList:clocklistobj]) {
NotificationCount = clocklistobj.incrementTag;
NSLog(#"NotificationCount : %i",NotificationCount);
clocklistobj.incrementTag =NotificationCount +1;
//insert increment tag in counter variable
counter = clocklistobj.incrementTag;
NSLog(#"counter when receive notification in delegate method: %i",counter);
NSLog(#"NotificationCount +1 & clocklistobj.incrementTag : %i",clocklistobj.incrementTag);
//set brightness of device
SetBrightnessValue = (float) (clocklistobj.incrementTag *0.066666);
NSLog(#"SetBrightnessValue : %f",SetBrightnessValue);
[[UIScreen mainScreen] setBrightness:SetBrightnessValue];
//set music player & control volume
setPlayerVolume = (float) (clocklistobj.incrementTag *0.066666);
NSLog(#"set Player Volume : %f",setPlayerVolume);
[audioPlayer setVolume:setPlayerVolume];
//below start playing audio
[audioPlayer play];
//update database
[sqldbobj UpdateNotificationCount:clocklistobj];
NSLog(#" After update clocklistobj.incrementTag:%i",clocklistobj.incrementTag);
if (clocklistobj.incrementTag ==15 || clocklistobj.incrementTag >15) {
NSLog(#"Notification reach at limit");
UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
// NSLog(#"eventArray : %#",eventArray);
for (int i=0; i<[eventArray count]; i++)
{
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
NSDictionary *userInfoCurrent = oneEvent.userInfo;
NSString *uid=[NSString stringWithFormat:#"%#",[userInfoCurrent valueForKey:#"ClockID"]];
NSInteger GetUid = [uid integerValue];
//here we cancell the particular notification
NSLog(#"Application is stoped clocklistobj.ClockIDvalue : %i", clocklistobj.ClockIDvalue);
if (GetUid ==clocklistobj.ClockIDvalue)
{
clocklistobj.soundisON = 0;
[sqldbobj UpdateAfteNotificationSwitchMakeOff:clocklistobj];
//Cancelling local notification
[app cancelLocalNotification:oneEvent];
break;
}
}
}else {
NSLog(#"Notification is off");
}
}
}
Ok so what you can do is you can restrict the user from setting multiple alarm at the same time.
For doing so you have to call [[UIApplication sharedApplication] scheduledLocalNotifications], it will provide you all the notifications scheduled till now.
Then you can go through these notification and check for the notification.fireDate if it matches your current scheduling fireDate then you can show an alert to user by saying that 'There is another alarm scheduled at the same time.'.
I have prepared an Alarm Clock app which uses UILocalnotification for scheduling the alarm.Now after the alarm has been set, I want to make a switch so that I can turn it ON and OFF usingUISwitch.I just cant figure how can I do that?What I am thinking as of now is that when you switch OFF the alarm, I shall store the DATE and TIME value before canceling the UILocalnotification so that when the user again switch ON the alarm I reschedule it with the stored DATE and TIME values. Is it the right way to do or is there any other ways to do that?
just make the database table which have 'date', 'isCanceled' field and unique id 'alarmId' columns (use rest whatever you want). so when the user wants to cancel the alarm try this,
NSString *alarmId = #"some_id_to_cancel";
UILocalNotification *notificationToCancel=nil;
for(UILocalNotification *aNotif in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
if([aNotif.userInfo objectForKey:#"ID"] isEqualToString:alarmId]) {
notificationToCancel = aNotif;
break;
}
}
[[UIApplication sharedApplication] cancelLocalNotification:notificationToCancel];
to use this better you create your alarm by,
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = itemDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertAction = NSLocalizedString(#"View Details", nil);
localNotif.alertBody = title;
localNotif.soundName = UILocalNotificationDefaultSoundName;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:stringID forKey:#"ID"];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
actually am developing an alarm project,
now i have a doubt on Local notification. how can i identify a particular notification.
we can't even set tag to local notification then how can i differentiate them.
example:
notification:1
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = selectedDate;
localNotification.alertBody = #"you got work";
localNotification.alertAction = #"Snooze";
localNotification.repeatInterval = NSDayCalendarUnit;
localNotification.soundName = UILocalNotificationDefaultSoundName;
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:#"setNotificationForEveryDay", #"key", nil];
localNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[localNotification release];
notification:2,
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = another selectedDate;
localNotification.alertBody = #"i got work";
localNotification.alertAction = #"Snooze";
localNotification.repeatInterval = NSDayCalendarUnit;
localNotification.soundName = UILocalNotificationDefaultSoundName;
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:#"setNotificationForEveryDay", #"key", nil];
localNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[localNotification release];
now i'm in situation to delete the second notification how can i do it...
please help me..
thanks in advance..
My guess is that use the userInfo for distinguishing the local notifications that would be a better idea but for that you need to set the userInfo of the local notification.
Like you could do something like this
if ([Your_notification_Object.userInfo valueForKey:#"Key 1"]==#"Object 1") {
NSLog(#"This is notification 1");
}
now for your second requirement i.e for the deleting part do you want to delete the notification when it is identified as n1 or n2 then in that case you could modify the above code and add this
if ([Your_notification_Object.userInfo valueForKey:#"Key 1"]==#"Object 1") {
NSLog(#"This is notification 1");
[[UIApplication sharedApplication] cancelLocalNotification:Your_notification_Object];
}
Place the above code as per your convenience