13

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'.

elsurudo
  • 3,579
  • 2
  • 31
  • 48

6 Answers6

11

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];
    }
}
Adil Soomro
  • 37,609
  • 9
  • 103
  • 153
reekris
  • 508
  • 7
  • 12
  • 1
    This will work so long as your app stays resident. As soon as it resigns, `currentNotifications` will be toast. I wish there were a way to list delivered notifications too, @elsurudo. – steveluscher May 14 '13 at 00:36
  • this is not working for me with ios 9.3.5, notification stays in the notification center – Marek Jalovec Sep 13 '16 at 09:19
6

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.

Justyn
  • 1,442
  • 12
  • 27
2

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.

dooleyo
  • 872
  • 1
  • 9
  • 13
1

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
}
CReaTuS
  • 2,593
  • 1
  • 19
  • 31
  • Yup, I've already read those. But what I want to do is remove a specific notification at a later (arbitrary) time, not just when it's first received. – elsurudo May 18 '12 at 12:25
1

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)

Community
  • 1
  • 1
Rygen
  • 309
  • 4
  • 15
0

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];
rishi
  • 11,779
  • 4
  • 40
  • 59
  • Oh, oops. In my actual code, I have a condition around [app cancelLocalNotification:localNotification], so cancelAllLocalNotifications won't do the trick. I'll update my code snippet to match this. – elsurudo May 18 '12 at 14:32