Setting the application badge number to 0 is not clearing notifications [duplicate] - ios

I've an iOS application where some Push Notification are sent to. My problem is, that the messages/notifications stays in the Notification Center in iOS after then are tapped. How can I remove a notification for my application in the Notification Center next time the application opens?
I came across posts where people are calling setApplicationIconBadgeNumber to a zero-value to clear the notifications. That's seems very weird to me, so I believe that maybe another solution exists?
EDIT1:
I'm having some problems clearing the notifications. Please see my code here:
- (void) clearNotifications {
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (launchOptions != nil)
{
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSLog(#"Launched from push notification: %#", dictionary);
[self clearNotifications];
}
}
return YES;
}
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
NSLog(#"Received notification: %#", userInfo);
[self clearNotifications];
}
I'm running the App through Xcode. When the App is minimized and I start the App using the notification in the Notification Center, I can see in the log, that the didReceiveRemoteNotification is called and using breakpoints I can see, that the clearNotifications has ran. But still the notification hangs in the Notification Center. Why?

Most likely because Notification Center is a relatively new feature, Apple didn't necessarily want to push a whole new paradigm for clearing notifications. So instead, they multi-purposed [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0]; to clear said notifications. It might seem a bit weird, and Apple might provide a more intuitive way to do this in the future, but for the time being it's the official way.
Myself, I use this snippet:
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
which never fails to clear all of the app's notifications from Notification Center.

Just to expand on pcperini's answer. As he mentions you will need to add the following code to your application:didFinishLaunchingWithOptions: method;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
You Also need to increment then decrement the badge in your application:didReceiveRemoteNotification: method if you are trying to clear the message from the message centre so that when a user enters you app from pressing a notification the message centre will also clear, ie;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];

It might also make sense to add a call to clearNotifications in applicationDidBecomeActive so that in case the application is in the background and comes back it will also clear the notifications.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[self clearNotifications];
}

Update for iOS 10 (Swift 3)
In order to clear all local notifications in iOS 10 apps, you should use the following code:
import UserNotifications
...
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests() // To remove all pending notifications which are not delivered yet but scheduled.
center.removeAllDeliveredNotifications() // To remove all delivered notifications
} else {
UIApplication.shared.cancelAllLocalNotifications()
}
This code handles the clearing of local notifications for iOS 10.x and all preceding versions of iOS. You will need to import UserNotifications for the iOS 10.x code.

If you have pending scheduled local notifications and don't want to use cancelAllLocalNotifications to clear old ones in Notification Center, you can also do the following:
[UIApplication sharedApplication].scheduledLocalNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
It appears that if you set the scheduledLocalNotifications it clears the old ones in Notification Center, and by setting it to itself, you retain the pending local notifications.

If you're coming here wondering the opposite (as I was), this post may be for you.
I couldn't figure out why my notifications were clearing when I cleared the badge...I manually increment the badge and then want to clear it when the user enters the app. That's no reason to clear out the notification center, though; they may still want to see or act on those notifications.
Negative 1 does the trick, luckily:
[UIApplication sharedApplication].applicationIconBadgeNumber = -1;

In Swift I'm using the following code inside my AppDelegate:
func applicationDidBecomeActive(application: UIApplication) {
application.applicationIconBadgeNumber = 0
application.cancelAllLocalNotifications()
}

Maybe in case there are scheduled alarms and uncleared app icon badges.
NSArray *scheduledLocalNotifications = [application scheduledLocalNotifications];
NSInteger applicationIconBadgeNumber = [application applicationIconBadgeNumber];
[application cancelAllLocalNotifications];
[application setApplicationIconBadgeNumber:0];
for (UILocalNotification* scheduledLocalNotification in scheduledLocalNotifications) {
[application scheduleLocalNotification:scheduledLocalNotification];
}
[application setApplicationIconBadgeNumber:applicationIconBadgeNumber];

When you have repeated notifications at future, you do not want to cancel those notifications, you can clear the item in notification center by:
func clearNotificationCenter() {
UIApplication.sharedApplication().applicationIconBadgeNumber = 1
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
}
You cannot clear notification when your app is open in the foreground by calling the method below immediately after receiving local notification, otherwise you will receive tens of hundreds of notifications. Maybe because the same notification apply again, and now is the time to fire, so you keep fire, apply again, fire, apply....:
[UIApplication sharedApplication].scheduledLocalNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;

When you logout from your app, at that time you have to use a below line of code on your logout button click method.
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
and this works perfectly in my app.

You need to add below code in your AppDelegate applicationDidBecomeActive method.
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];

Got it from here. It works for iOS 9
UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++)
{
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
//Cancelling local notification
[app cancelLocalNotification:oneEvent];
}

Related

CancelAllLocalNotifications Not Working Sometimes

Every time my app enter background, I call [[UIApplication sharedApplication] cancelAllLocalNotifications]; first.Then I reschedule localnotifications as need.
But sometimes localnotification that scheduled long time ago and should be canceled still fired.I put create time in userinfo of each localnotification. In didReceiveLocalNotification:(UILocalNotification *)notification method I get create time of this notification. And cancelAllLocalNotifications was called after that time. So I'm 100% sure this notification should be canceled.It's so wired that it still fired!
My app was tested on iOS9.0.2.Does any one has similar problem?
Use this way for remove one by one Local Notification of app. It's working, exactly as you want.
NSArray *arrayLocalNotif = [[UIApplication sharedApplication] scheduledLocalNotifications] ;
for (UILocalNotification *localNotification in arrayLocalNotif) {
[[UIApplication sharedApplication] cancelLocalNotification:localNotification] ;
}

Remote Push Notification badge count not increasing when app is in background

I am working on remote push notification and getting badge count in payload. it's working fine when my app is active(foreground) but when app run in background and i got push then badge count not increases. Please help.
when app is active it calls didReceiveNotification method.
I am receiving this type of info in payload.
{aps = {alert = "Hi all.";badge = 6;sound = default;};}
I am not sure where is issue.
Try this
-(void)applicationDidBecomeActive:(UIApplication *)application
{
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] cancelAllNotifications];
}

Can not remove push notification from notification center

[[UIApplication sharedApplication] cancelAllLocalNotifications];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];'
I added the above code to didfinishLaunchingWithOptions but when a user taps a notification in his notification center and enters my app the notification does not gets cleared.
Edit:
I also tried adding this to my code:
You Also need to increment then decrement the badge in your
application:didReceiveRemoteNotification: method if you are trying
to clear the message from the message centre so that when a user
enters you app from pressing a notification the message centre will
also clear, ie:
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
as describes here: iOS application: how to clear notifications? but the notification still won't clear from the notification center
I just Added a Badge number manually to my application and pasted
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
To my AppDelegate. For me this works like a charm.
Note that didfinishLaunchingWithOptions and applicationDidBecomeActive are not the same as Mouhammad Lamaa explained. If you paste this to your AppDelegate and tap the notification in notification center it should disapper. If it does not your App maybe creates a new Notification after becoming active?
add this code
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
the didfinishlaunchingwithoptions launched at the initial launch of your app. if your app the running in the background, didfinishlaunchingwithoptions will not be launched.
When the user open application from notification action - it launches with
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *remoteNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif) {
//handle remote notification
}
....
}
But when the app was in background it calls
- application:didReceiveRemoteNotification:
Also method [[UIApplication sharedApplication] cancelAllLocalNotifications]; cancel registered LOCAL notifications only. Push notifications can't be canceled - they delivered immediately and executed only once.

Dismiss an already delivered UILocalNotification?

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];

How to Remove Push Notification in Notification Center after viewed

Is there any way to handle the push notification from the Notification Center after being tap, and remove it when my application has already launched?
I know this is hack and slash, but you can clear all notifications by changing the badge number on your application.
- (void)application:(UIApplication*)application didReceiveRemoteNotification (NSDictionary*)payload
{
NSLog(#"Received notification: %#", payload);
//swapping between two badge numbers to clear notifications
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
...
}
If you already had a badge number you don't want to lose (above example will simply clear badge number in the end) you can do something like
- (void)application:(UIApplication*)application didReceiveRemoteNotification (NSDictionary*)payload
{
NSLog(#"Received notification: %#", payload);
/*
storing current badge number then swapping between 2 values to make sure we
clear the badge number. Once this is done set badge number back to original
value.
*/
int badgeNum = [[UIApplication sharedApplication] applicationIconBadgeNumber]
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeNum];
...
}
This may not be best practice, but it gets the job done and the client will not know the difference. I like to call it a temp. fix until I stumble upon a better solution. Hope this helps someone!

Resources