It could be a possible duplicate link of.
Remove single remote notification from Notification Center
According to this post we can't delete single notification from notification center(NC).
For canceling notification we have below methods.
1).cancelAllLocalNotifications : it remove all notification.
2).cancelLocalNotification : it require notification as input.
I tried both methods, using first one it remove all notification from NC and the second one not seems work.
Here is the second snippet which I am applying on didRecivedRemoteNoitification method.
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);
int notiid=[[userInfoCurrent valueForKey:#"notificationID"] intValue];
if (notiid ==deletenotiid)
{
//Cancelling local notification
[app cancelLocalNotification:oneEvent];
break;
}
}
So my question is I am seeing couple of application that remove the tapped one notification from NC for example skype
Is there something which I am missing to apply.
Thanks for your valuable time.
You wrote that you included the above code in didRecivedRemoteNoitification. However, didRecivedRemoteNoitification is called only when a push notification arrives while the app is running in the foreground, in which case no notification is displayed and there is nothing to clear.
For notifications that arrive while the app is not running, when a user taps the notification, the notification data is passed to application:didFinishLaunchingWithOptions:. I think the tapped notification will be cleared if you clear the badge number.
- (void)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opts {
// check launchOptions for notification payload and custom data, set UI context
[self startDownloadingDataFromProvider]; // custom method
app.applicationIconBadgeNumber = 0;
// other setup tasks here....
}
Related
How do i handle (open alert for) all the UILocalNotification on click of one notification since apple clears other notification from notification center on click of one notification...also if the user opens the app ignoring the notifications in notification center, how do i handle(open UIAlertView for) them as well? i have seen this working perfectly in Calminder app
You can use [[UIApplication sharedApplication] scheduledLocalNotifications]; to get all the notifications that are previously scheduled. This method returns an NSArray instance so you can run a for loop to handle these:
for (UILocalNotification *notification in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
// Handling codes goes here.
}
If you wants to have some extra informations in the notification you can use the userInfo property. It is a dictionary to store additional informations along the notification. You can set it like this:
notification.userInfo = // The dictionary goes here.
So now you can do this:
for (UILocalNotification *notification in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
NSDictionary *userInfo = notification.userInfo;
// Handling codes goes here. Now you can use the user info dictionary to
// get what you stored into the userInfo dictionary when you are
// initializing the user info.
}
After this you can get all the informations and you can present it in an UIAlertView.
To call these codes above at app's launch you can use two methods:
-application:didFinishLaunchingWithOptions:
or
-applicationDidBecomeActive:
Hope this helps.
I am not sure if this is possible, but I need to grab all of the push notification userinfo when the user opens up the App. I can get all of the push notification userinfo when the App is opened or in the background, but not when the App is completely closed. Any way around this? The code below is how I get the userInfo currently.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
id data = [userInfo objectForKey:#"data"];
NSLog(#"data%#",data);
}
Unfortunately, it's not currently possible client side with that method to query old notifications that have occurred while the app was completely closed. See this question: didReceiveRemoteNotification when in background.
A way around it is to keep track of which notifications you send from your server per user. When didReceiveRemoteNotification: is called, you can take that notification and compare it against the server's messages for the current user. If one of them matches, mark it some way on the server. That way, if there are messages sent when your app is backgrounded, you can query for messages that haven't been marked from the server and get all 'missed' notifications.
The method you are implementing cannot handle both cases. See the "Local and Push Notification Programming Guide":
If your app is frontmost, the application:didReceiveRemoteNotification: or application:didReceiveLocalNotification: method is called on its app delegate. If your app is not frontmost or not running, you handle the notifications by checking the options dictionary passed to the application:didFinishLaunchingWithOptions: of your app delegate...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Notifications
NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo){
//open from notification message
}
return YES;
}
You can add this code to your AppDelegate's applicationWillEnterForeground method:
-(void)applicationWillEnterForeground:(UIApplication *)application {
// this method is called when staring an app that was closed / killed / never run before (after applicationDidFinishLaunchingWithOptions) and every time the app is reopened or change status from background to foreground (ex. returning from a mobile call or after the user switched to other app and then came back)
[[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
NSLog(#"AppDelegate-getDeliveredNotificationsWithCompletionHandler there were %lu notifications in notification center", (unsigned long)[notifications count]);
for (UNNotification* notification in notifications) {
NSDictionary *userInfo = notification.request.content.userInfo;
if (userInfo) {
NSLog(#"Processed a notification in getDeliveredNotificationsWithCompletionHandler, with this info: %#", userInfo);
[self showPushNotificationInAlertController:userInfo]; // this is my method to display the notification in an UIAlertController
}
}
UIApplication.sharedApplication.applicationIconBadgeNumber = 0;
}];
}
}
Remove this line from the method application didFinishLaunchingWithOptions: if you had included it there, because it clears the badge number and also all notifications in notifications center:
UIApplication.sharedApplication.applicationIconBadgeNumber = 0;
This is currently working in iOS 12, hadn't had the chance to test it in earlier versions.
My App receives APNS Push Notifications, and when a user receive more than one NSNotification, he should be able to open the app in a specific view according the NSNotification tapped.
So in the method
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler
I added this code to save all the notifications
if (self.notifications == nil) {
self.notifications = [[NSMutableArray alloc] init];
}
[notifications addObject:userInfo];
And every time the app becomes active again it does this
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started)
// while the application was inactive.
// If the application was previously in the background,
// optionally refresh the user interface.
[notifications removeAllObjects];
application.applicationIconBadgeNumber = 0;
}
Before removing all the objects and setting the badge to zero, I would like to handle which NSNotification made my app open from the background. And once I have which push NSNotification it was, I would like to pass all the data to a specific view.
Based on your comment about UILocalNotification usage
UILocalNotification has a userInfo property. When you create your local notification from the push notification, set the appropriate information into this property and then when the app delegate receives application:didReceiveLocalNotification: you can use that into to update your UI.
If you not use new iOS7 background fetch notifications.
In - (void)applicationDidBecomeActive:(UIApplication *)application before removing all object from notification array, check for notification
NSDictionary * myNotification = [notifications lastObject];
if (myNotification)
{
// is last notification
}
Is will work because app receive only notification that user tap on it
Send with your push notification, data, and use it when your app receives it.
In this example, i'm using the image file and alert, and sending it to all the views that are registered for this Notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//Posting the notificaiton to the use, if its valid:
NSDictionary *returnDic = [userInfo objectForKey:#"aps"];
if (![returnDic objectForKey:#"alert"]) {
return;
}
NSString *alert = [NSString stringWithFormat:#"%#",[returnDic objectForKey:#"alert"]];
if (![returnDic objectForKey:#"MagnetID"]) {
return;
}
NSString *magnetImage = [returnDic objectForKey:#"MagnetImage"];
NSDictionary *dictionaryToSend = [NSDictionary dictionaryWithObjectsAndKeys:magnetImage,MAGNET_IMAGE,alert,MAGNET_ERROR_MESSEGE, nil];
//Posting to the rest of the views, the messege:
[[NSNotificationCenter defaultCenter] postNotificationName:USER_MESSEGE_RECEAVED object:nil userInfo:dictionaryToSend];
NSLog(#"Notifications - userInfo=%#",userInfo);
}
What you may do, is save the data that you need, by UserDefults or whatever you prefer, and at the "applicationDidBecomeActive" method, use that data to show the right view.
Hope this helps
I know I can cancel the notification when user tap this notification in notification center . But can I cancel the notification in other palce where I can't get the related local notification from system. Can I serialize the local notification, and cancel it when the app runs next time?
Sorry for make you misunderstand!
I want to dismiss a posted notification in the notification center, but not a scheduled one.
So what I want to ask is how to save the local notification object, then I can use it dismiss itself when next time the app launch. Maybe this job can't be done with current sdk.
If you need to cancel all notification you can use:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
For cancelling a particular notification:
[[UIApplication sharedApplication] cancelLocalNotification:aNotification];
For getting the particular Notification you can use:
NSArray *notifArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (int i = 0; i < [notifArray count]; i++)
{
UILocalNotification *aEvent = [notifArray objectAtIndex:i];
NSDictionary *userInfo = aEvent.userInfo;
NSString *notifId=[NSString stringWithFormat:#"%#",[userInfo valueForKey:#"id"]];
if ([id isEqualToString:cancelId])
{
[[UIApplication sharedApplication] cancelLocalNotification:aEvent];
break;
}
}
Here:
You need to store a id key value pair in the userInfo of your notification for identifying particular local notification
cancelId is the id of notification which you want to cancel (Stored in user info)
If you save a link to your notification, then you will can cancel it before it fires.
[[UIApplication sharedApplication]cancelLocalNotification:yourNotification];
Use this Code to get all scheduled notifications:
NSArray *reminderArray=[[UIApplication sharedApplication]scheduledLocalNotifications];
Then you can select the notification required and delete it.
[[UIApplication sharedApplication]cancelLocalNotification:yourNotification];
Is it possible to do this? UIApplication's scheduledLocalNotifications doesn't seem to return notifications that have already been delivered to the user's notification center, so I think this may be by design, but I can't find any documented evidence of this.
Anyone know?
Thanks!
EDIT: Found this:
You can cancel a specific scheduled notification by calling
cancelLocalNotification: on the application object, and you can cancel
all scheduled notifications by calling cancelAllLocalNotifications.
Both of these methods also programmatically dismiss a currently
Here: http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/IPhoneOSClientImp/IPhoneOSClientImp.html
However, how do I get a reference to an already-delivered notification, if scheduledLocalNotifications doesn't give me notifications that have already been delivered?
EDIT 2:
Here's what I'm trying to do, after I've registered some notifications:
UIApplication *app = [UIApplication sharedApplication];
for (UILocalNotification *localNotification in app.scheduledLocalNotifications)
{
if (someCondition) {
[app cancelLocalNotification:localNotification];
}
}
}
The problem is that once they're delivered, they're no longer in 'scheduledLocalNotifications'.
You can solve this by adding your newly created notifications to your own NSMutableArray of notifications and check that array instead of app.scheduledLocalNotifications.
Something like this:
Add a NSMutableArray to your Viewcontrollers .h file:
NSMutableArray *currentNotifications;
Initiate it when initiating your ViewController
currentNotifications = [[NSMutableArray alloc] init];
When initiating a notification, also add it to your array:
UILocalNotification *notification = [[UILocalNotification alloc] init];
...
[currentNotifications addObject:notification];
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
Later when you want to cancel that notification, look for it in your array instead.
Also remove it from your array:
for (UILocalNotification *notification in currentNotifications) {
if (someCondition) {
[[UIApplication sharedApplication] cancelLocalNotification:notification];
[currentNotifications removeObject:notification];
}
}
Since iOS10 there is now native support for this if you have transitioned to using UNUserNotificationCenter.
The Apple docs state:
func getDeliveredNotifications(completionHandler: #escaping ([UNNotification]) -> Void)
Provides you with a list of the app’s notifications that are still displayed in Notification Center.
func removeDeliveredNotifications(withIdentifiers: [String])
Removes the specified notifications from Notification Center.
func removeAllDeliveredNotifications()
Removes all of the app’s notifications from Notification Center.
I've been looking for an answer to this as well. My problem was that I wanted to 'clean up' all app-related notifications sitting in the notification center just in case the user opens the app from its dock icon (since that does nothing to the previously fired notifications...)
Fortunately, it would appear that cancelAllNotifications doesn't just cancel scheduled ones, but EVERYTHING. So I simply held on to a reference of the existing scheduled notifications before blasting them, and then rescheduled them accordingly:
UIApplication *app = [UIApplication sharedApplication];
NSLog(#"\nScheduled notif count (prior) = %d", app.scheduledLocalNotifications.count);
NSArray *scheduledNotifs = app.scheduledLocalNotifications; // hold on to a reference
[[UIApplication sharedApplication] cancelAllLocalNotifications]; // blast everything
NSLog(#"\nScheduled notif count (post-wipeout) = %d", app.scheduledLocalNotifications.count);
for (UILocalNotification *notif in scheduledNotifs) {
[app scheduleLocalNotification:notif]; // put them back
}
NSLog(#"\nScheduled notif count (post-repopulation) = %d", app.scheduledLocalNotifications.count);
Not sure if that helps anyone but this worked great for my situation.
Try this links:
Apple doc
Some tutorial
And local notification is registering to device notification center, not in your app.
But, if your app is running, and is a notification time, then you can get notification parameters in game in:
-(void) application:(UIApplication*)app didReceiveLocalNotification:(UILocalNotification*) notification
{
// local notification is geted
}
You can do it when you schedule the notification if you also save it in NSUserDefaults, using NSKeyedArchiver to convert it to NSData.
To get it back as UILocalNotification you use NSKeyedUnarchiver. Then you're able to delete it using the cancelLocalNotification method.
Fully explained here (Swift version + link to original Obj-C solution)
After seeing your updated code, it seems you are interested in cancel all the notifications with-in for loop, so you can use -
[[UIApplication sharedApplication] cancelAllLocalNotifications];