109

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?

John Topley
  • 113,588
  • 46
  • 195
  • 237
dhrm
  • 14,335
  • 34
  • 117
  • 183

12 Answers12

157

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.

Patrick Perini
  • 22,555
  • 12
  • 59
  • 88
  • 1
    cancelAllLocalNotifications is Deprecated - https://developer.apple.com/documentation/uikit/uiapplication/1622990-cancelalllocalnotifications?language=objc You need to use `let center = UNUserNotificationCenter.current() center.removeAllDeliveredNotifications() // To remove all delivered notifications` https://stackoverflow.com/a/40397907/1155650 – Rohit Vipin Mathews Jun 15 '20 at 08:30
119

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];
ADAM
  • 3,903
  • 4
  • 29
  • 45
  • I think cancelAllLocalNotifications is not required.Worked for me without that line – Murali Oct 08 '15 at 11:46
  • @Murali would that depend on you using **local** notifications or not...? – Alejandro Iván Nov 23 '15 at 19:55
  • 1
    UPDATE:: “cancelAllLocalNotifications' is deprecated: first deprecated in iOS 10.0” So if your app version is higher than iOS10.0 then you should use this UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center removeAllDeliveredNotifications]; [center removeAllPendingNotificationRequests]; – User18474728 Jul 09 '18 at 01:11
21

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];
}
bert
  • 1,556
  • 13
  • 15
17

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.

GKFX
  • 1,386
  • 1
  • 11
  • 30
James Stonehill
  • 1,125
  • 10
  • 22
9

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.

ospr
  • 1,650
  • 2
  • 17
  • 21
  • 1
    This works like a charm for me on iOS 9. I didn't want to cancel all my notifications because they repeat in time (daily or weekly). And this way I clear all the stuff without deleting them. – superpuccio Nov 30 '15 at 16:11
  • 1
    Best solution I have seen so far. Anyone know if it works on iOS 8? – duncanc4 Dec 04 '15 at 18:10
  • @duncanc4 last time I tested it on iOS 8 it was working. – ospr Dec 04 '15 at 21:32
  • Where within the app would you call this? – Alex Zavatone Jan 15 '16 at 15:02
  • Alex, you should call it whenever you need to clear out the notifications in the Notification Center. I call it in both my AppDelegate's `applicationDidBecomeActive:` and `application:didReceiveLocalNotification:` methods. – ospr Jan 15 '16 at 16:13
  • You cannot call this method immediately after receiving local notification because you will receive tens of hundreds notification. Maybe the same notification apply again, and now is the time to fire, so you keep fire, apply again, fire, apply.... – zgjie Jun 01 '16 at 07:57
  • @zgjie I've been using this without any issues for a while now and just tried your use case and was unable to reproduce. I'd be very interested if you have a sample project that can reproduce this. – ospr Jun 02 '16 at 15:11
  • Very nice! But is this documented functionality or 'just' a side effect of the current implementation which may change in any minor/major iOS update? – meaning-matters Oct 25 '16 at 08:17
  • @meaning-matters As far as I know this is not documented and it could change in an iOS update. However, also as far as I know there is no official way of doing this. If you look at the other answers they are all just "hacks" to clear out stale notifications from the notification center. For example the top answers have you clear out the badge and end all pending local notifications. Neither have anything to do with clearing out old/stale notifications from notification center. This particular answer solved the problem and allowed me to keep pending/scheduled notifications. – ospr Oct 25 '16 at 15:54
4

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;
Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
TahoeWolverine
  • 1,749
  • 2
  • 23
  • 31
  • 1
    Does it work for you in iOS9? I didn't noticed any difference with setting a badge to 0 or to -1. It still clears all remote notifications in my case. – AlexeyVMP Feb 25 '16 at 11:04
  • Ya, I actually started noticing that with my app again; I have no idea what changed. – TahoeWolverine Mar 31 '16 at 00:18
  • I'm giving up since Apple somehow decided that app with no badge number should have no any notifications – AlexeyVMP Mar 31 '16 at 09:39
3

In Swift I'm using the following code inside my AppDelegate:

func applicationDidBecomeActive(application: UIApplication) {
    application.applicationIconBadgeNumber = 0
    application.cancelAllLocalNotifications()
}
Antoine
  • 23,526
  • 11
  • 88
  • 94
1

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];
Alex Zavatone
  • 4,106
  • 36
  • 54
0

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;
zgjie
  • 2,099
  • 2
  • 21
  • 32
0

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.

Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
Vaibhav Shiledar
  • 939
  • 8
  • 15
0

You need to add below code in your AppDelegate applicationDidBecomeActive method.

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
Bhavesh Patel
  • 596
  • 4
  • 17
-1

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];
}
Community
  • 1
  • 1
Dan L
  • 19
  • 2