In this application that I'm trying to make, I use push notifications. This part works just fine. When I send a notification I also add a badge to the app icon. The problem is when I lunch the application it should disappear again, but it does not.
-(IBAction)Push{
NSMutableDictionary *data = [NSMutableDictionary dictionary];
[data setObject:#"Numfeud: Troels made a move!" forKey:#"alert"];
[data setObject:[NSNumber numberWithInt:1] forKey:#"badge"];
[data setObject:#"bar" forKey:#"foo"];
[PFPush sendPushDataToChannelInBackground:#"GameChannel2" withData:data];
}
In the application didFinishLaunchingWithOptions I try to set badge to 0 in this way:
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
How can I clear the application icon badge?
If your app becomes active again and is still in the background you should reset the badge count in -applicationDidBecomeActive: as well:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
If your app is still running in the background -application:didFinishLaunchingWithOptions: won't be called.
Likely, -application:didFinishLaunchingWithOptions: is not being called, because your app is still running in the background. In order to remove the badge count when the app is launched from the background you'll have to reset the badge number in -applicationWillEnterForeground:, too.
In Swift and In AppDelegate
func applicationDidBecomeActive(_ application: UIApplication) {
application.applicationIconBadgeNumber = 0
}
You can use this codes also.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
or In a specific ViewController
- (void)awakeFromNib {
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
Maybe call it in applicationWillResignActive (in AppDelegate.m):
-(void)applicationWillResignActive:(UIApplication *)application{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
This will help you to clear badge if push come when app is being open. User seeing notification and you clear it, when he press Home Button (once or twice). Also it will be clear if app being closed (clear after user open it).
Here you can see when this method called.
Related
I have created a UILocalNotification with
localNotification.fireDate = [CurrentDate dateByAddingTimeInterval:+60
So, After 60s, it will notification for me.
And my AppDelegate, I have call method.
(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// Request to reload table view data
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
NSLog(#"OK...");
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
When I click on notification, it is called didReceiveLocalNotification method. It is OK.
But when I click in App's Icon in screen, it is not called didReceiveLocalNotification method.
I have research and followed this code in didFinishLaunchingWithOptions
// Handle launching from a notification
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
// If not nil, the application was based on an incoming notifiation
if (notification){
NSLog(#"test...");
}
But, it is not working.
It is get notification = nil.
So, it is not NSLog(#"test...");
Please help me!
when app icon is clicked its not local notification click, where as your code in didFinishLaunchingWithOptions works in the case when app is not running in background and user or you click on local notification. Whereas whenever app icon is clicked not always didFinishLaunchingWithOptionsis called, it is called only when app starts i.e not present in background but, applicationDidBecomeActive is called whenever app starts from anywhere in any mode. UIApplicationDelegate [https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol]
I have a app to which i can send push notifications using pushbots. The user is able to receive the notification and on clicking it he/she can open the app. However the badge notification still shows that there is a notification. How would i set my notification badge to 0.
This is my appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Register for Remote Notifications
[Pushbots sharedInstanceWithAppId:#"5503e09a1d0ab1481f8b45a1"];
NSDictionary * userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo) {
// Notification Message
NSString* notificationMsg = [userInfo valueForKey:#"alert"];
// Custom Field
NSString* title = [userInfo valueForKey:#"title"];
NSLog(#"Notification Msg is %# and Custom field title = %#", notificationMsg , title);
}
return YES;
}
-(void)onReceivePushNotification:(NSDictionary *) pushDict andPayload:(NSDictionary *)payload {
NSString* message = [pushDict valueForKey:#"alert"];
UIAlertView *alertMessage = [[UIAlertView alloc] initWithTitle:#"New Event !" message:message delegate:self cancelButtonTitle:#"Open" otherButtonTitles: #"I will check later",nil];
[alertMessage show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
Pushbots * pushbots = [Pushbots sharedInstance];
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Open"]) {
[pushbots OpenedNotification];
}
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (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.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
You can call this in your application :
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
Obviously this needs a little more work. If you're dealing with messages for example, you'd need to decrement the badge number by the number of messages read and make sure to not go below zero.
You can also use the "badge" key to modify the current badge through the notification payload itself.
for example use
{..., "badge" : "increment", ...}
or
{...,"badge" : 3, ...}
The first one would be the most frequent version i'm guessing.
But if your app is fairly simple, then just call this and your badge will be set to zero.
I'd advise you to update your pushbots lib to 1.1 and use the following method which will clear the badge locally and on the server:
[[Pushbots sharedInstance] clearBadgeCount];
For Swift 3
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
Pushbots.sharedInstance().clearBadgeCount()
}
func applicationWillEnterForeground(application: UIApplication)
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
Pushbots.sharedInstance().clearBadgeCount()
}
Objective C
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
[[Pushbots sharedInstance] clearBadgeCount];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
[[Pushbots sharedInstance] clearBadgeCount];
}
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
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....
}
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];
}