Increment the Push notification Badge iPhone - iphone

Is it possible to increment the badge value on receiving the notification. OR Should I send the count as payload?
If i am sending the badge value as "1" every time, how could i increment the badge-value in the icon of the app if the app is not open.
i have used this code but doesn't work.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + 1;
}

Usually in all apps the unread notification counts are maintained in the server. When the server sends a push notification to a particular device token they send the badge count along with the payload. Once the device is notified and your app is in background(or killed) the OS automatically update the badge count to your app icon. In case whether you have your app running, you will get notified in the
application:didReceiveRemoteNotification:
delegate and thus you are able to receive the badge count from the (NSDictionary *)userInfo. And thus you are able to update the app icon badge count using the function
[UIApplication sharedApplication].applicationIconBadgeNumber = [[[userInfo objectForKey:#"aps"] objectForKey: #"badgecount"] intValue];
Think this should help you.

If the application is not open you will not be able to increase the badge except from the payload.

When a Push Notification comes while your application is in background mode & you want to increment the Badge Number, you should send a badgeCount to the server, so that the server knows the current count.
If you manage the badge count from the Server Side then this code is enough:-
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"remote notification: %#",[userInfo description]);
if (userInfo) {
NSLog(#"%#",userInfo);
if ([userInfo objectForKey:#"aps"]) {
if([[userInfo objectForKey:#"aps"] objectForKey:#"badgecount"]) {
[UIApplication sharedApplication].applicationIconBadgeNumber = [[[userInfo objectForKey:#"aps"] objectForKey: #"badgecount"] intValue];
}
}
}
}

Urban Airship supports this using their "autobadge" feature.

After receiving remote Notification when you open App,
get current Badge number in "didBecomeActive" Method of your Appdelegate File using below code:
int badgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
badgeCount = badgeCount + 1;

Related

Cancel Remote Notifications ,let it not show at the notification center

My app is close ,and screen is lock,when I receive a remote push notification,it appear on the screen,when I slide the notification but not slide the lock,it can open my app,all is OK.but the notification always appear at notification center,not disappear. How to dismiss it from the notification center,when I slide the notification.
(void)applicationDidFinishLaunching:(UIApplication *)application{
// put receive remote notification is here
}
is there have some api like cancel localnotificationg,cancel remote notification?
Set the applicationIconBadgeNumber property of your UIApplucation object to zero. This will clear tge notifications from notification center.
Where you handle the notification, you need to reset applicationIconBadgeNumber property.
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
This should be ideally at the place of Custom Code in following snippet:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Received notification: %#", userInfo);
//[self addMessageFromRemoteNotification:userInfo];
NSString* alertValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
NSLog(#"my message-- %#",alertValue);
badgeValue= [alertValue intValue];
[UIApplication sharedApplication].applicationIconBadgeNumber += badgeValue;
//
//Custom Code where you actually respond to the notification.
//
}

User taps on UILocalNotification: Can it pass data to the app?

I am creating a local UILocalNotification and displaying it to the user as a banner. Is it possible to set it up so that when the user taps it and returns to the app, the app will receive some kind of data on the specific kind of notification it was? I want to open a specific view controller in the app. I think the best way would be to essentially send a URL to the app, or is there a way to get access to the UILocalNotification so that I can test which kind is was and do the right action?
To get data from the local NSUserNotification that is passed to an iOS app, all that you need to do is implement the following method: - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification.
The problem is, this is called both when a local notification is posted when the app is in the background (i.e. when the user taps on the notification and then returns to the app), and also if the app is in the foreground at the time when the local notification fires (it is on a timer, after all). So how should one figure out if the notification was fired when the app was in the background or foreground? It's pretty simple. Here's my code:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
} else {
// App was running in the foreground. Perhaps
// show a UIAlertView to ask them what they want to do?
}
}
At this point you can handle the notification based on notification.userInfo, which holds a NSDictionary.
ust implement the NSUserNotificationCenterDelegate and define this method:
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
Example:
This is what I did in a "notifier" application.
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
NSRunAlertPanel([notification title], [notification informativeText], #"Ok", nil, nil);
}
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
notifications=nil;
[tableView reloadData];
[center removeDeliveredNotification: notification];
}
When the notification is activated (click by the user) I just inform the user with a panel (I could use a hud window).In this case I immediately remove the delivered notification, but this is not what happens usually.The notification could stay there some time and be removed after 1/2 hours (it depends on the application that you are developing).
1 - Define some class in your project to implement NSUserNoficationCenterDelegate protocol (documented here)
#interface someObject : NSObject <NSUserNotificationCenterDelegate>
{
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification;
}
2 - Set an instance of the object defined #1 as the delegate of default notification center.
[[NSUserNotificationCenter defaultNotificationCenter] setDelegate: someObject];
Now you will get called on didActivateNotification any time the user taps/clicks on the notification. You will have the original notification you created. So any information that you need should be available to you.
If you want/need special information (other than notification title, message, etc) you will probably need to set additional application specific information in your notification before you schedule it to be sent. For example:
NSUserNotification* notification = [[NSUserNotification alloc] init];
NSDictionary* specialInformation = [NSDictionary dictionaryWithObjectsAndKeys: #"specialValue", #"specialKey", nil];
[notification setUserInfo:specialInformation];

How to create a custom alarm which can be set for random days in a week without using local notifications?

I have studied some of the following questions, that are::
1.) How to set alarm for selected days in iphone?
2.) iPhone alarm using repeated local notifications
3.) How to set the alarm in iPhone and save in local notification?
but they all are using local notifications. I am facing problem with local notification as I have to use three buttons on an Alarm View which are: Snooze, Ignore and Okay. I have to perform custom actions on each button click.
Please help me with this stuff.
Suggestions accepted.
Thanks in advance.
Kuldeep.
In you app delegate...
- (void) presentWidget: (NSString*)theDisplayedText {
BOOL widgetIspresent = [WidgetVC widgetIsCurrentlyPresented];
if (!widgetIspresent) {
WidgetVC *widgetVC = [[WidgetVC alloc] initWithNibName:#"WidgetVC" userInfoString:theDisplayedText bundle:nil];
widgetVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
widgetVC.userInfoStr = theDisplayedText;
[mainScreenManager presentViewController:widgetVC animated:YES completion:nil];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSLog(#"Recieved Notification didFinishLaunchingWithOptions %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
//here we have to handle whatever notification was pressed - that might also be an old aready passed one
//this all is checked when the widget opens - it will show if the notification is OK or too old
[self presentWidget: theDisplaytext ];
} else {
//so we started the app normally, not via local notification
[self presentWidget];
}
return YES;
}
// Handle the notificaton when the app is running
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotif {
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification didReceiveLocalNotification %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
[self presentWidget: theDisplaytext];
}
You need a way to start the UIViewController for the widget, I just created a mainScreenManager helper.
So on the widgetVC you have your "Snooze" and "OK" while the "Ignore" is just the ignoring of the notification itself.
Hope this gets you on an usable track...
ps I ported my app from Android to iPhone, that's why I used the name "widgetVC" for this screen. On Android it is implemented as a widget. Hope no iPhone lover feels offended :-)

How to change application badge with push when application is closed

I'm trying to change the badge of the application I'm developing. When closed, unfortunately I was only notified a message without changing the badge.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge];
NSDictionary* userInfo = [launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"];
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSInteger badge = [[apsInfo objectForKey:#"badge"] integerValue];
if( [apsInfo objectForKey:#"alert"] != NULL)
{
application.applicationIconBadgeNumber = badge;
}
But that does not change anything. I have not found any solution around. What method is invoked on arrival of a push notification and the application is closed? I also added:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
#if !TARGET_IPHONE_SIMULATOR
NSLog(#"remote notification: %#",[userInfo description]);
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSString *alert = [apsInfo objectForKey:#"alert"];
NSLog(#"Received Push Alert: %#", alert);
NSString *badge = [apsInfo objectForKey:#"badge"];
NSLog(#"Received Push Badge: %#", badge);
application.applicationIconBadgeNumber = [[apsInfo objectForKey:#"badge"] integerValue];
#endif
}
But nothing...
Can you help me?
The badge icon number is governed by the badge property in the payload received as push message. The app itself has no role to play in what number shows up till the app becomes active. Setting the 'badge' property to any integer value (Note : it should not be string and should NOT be enclosed within "") does what is needed. The OS on receiving the notification looks for the value for 'badge' and immediately sets it on the app badge icon. All this happens when app is not active. To make sure it increments or decrements based on what happens in the app, the app should send message to server with the updated badge number.
In the active state, it is app's responsibility to handle the remote notification and change the badge icon.
Note : 'badge' property is enclosed in the 'aps' dictionary received within the payload. My payload looks like :
aps = {
alert = "Push notification!";
badge = 9;
sound = default;
}
You should define better what you want to do because it is not clear to me if wether you are talking about remote or local notifications, or what exactly you want to get and what are you getting.
Anyway, regarding remote notifications (APNS), take into account that you should set the badge as part of the payload if you want it to be set with the app closed. Your app does not get invoked unless the user manually opens the app (from the NotificationCenter or the dock).
On the other hand, when you are running the app, you will receive the call to
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
in your AppDelegate, and then you can set the badge by using
application.applicationIconBadgeNumber = badge;
Look at this, maybe it is a settings problem!:
application Icon Badge Number in ios5
Try also to give applicationIconBadgeNumber an int value, not NSInteger.
OK. Now my report about strange things.
I got it! It works good for now.
Problem was:
i created my App with push notification everything was ok with simple integer (1,8,99) but then i noticed that my integer 35.06 in the PHP variable $price did not recognize it at all even (int)$price unsuccessful . I thought the number is too long (but actually 4 digits is very popular). I decided to use
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
but as it was mentioned it does not work at all when the App is not started. No chance. It will never update the badge. I spent a lot of time thinking about what could be wrong and suddenly something came on my mind.
in the payload i just did this
'badge' => $price*100
an of course it worked good for me =)
I dont know what is the problem , why didn't work (int)$price (it is actually integer) but it is ok now.
My badge shows now something like this 3.506 and of course you can move the dot on step and you have your 35.06
Hope it could help you.

didReceiveRemoteNotification when in background

These kind of question has been asked a number of times but i have some specific situation going on.
When my application is active and I receive a PUSH message i'm successfully able to parse the custom payloads and such.
However when my application is in the background and the PUSH arrives the user has to click on the 'View/Open' button in order to get the didReceiveRemoteNotification called and the didFinishLaunchingWithOptions is called after that.
I need to have my application decide if they have to prompt the user with an UIAlert when in the background or suppress the push message based on some local settings.
Any help would be appreciated,
You app needs to handle all the possible push notification delivery states:
Your app was just launched
Your app was just brought from background to foreground
Your app was already running in the foreground
You do not get to choose at delivery time what presentation method is used to present the push notification, that is encoded in the notification itself (optional alert, badge number, sound). But since you presumably are in control of both the app and the payload of the push notification, you can specify in the payload whether or not there was an alert view and message already presented to the user. Only in the case of the app is already running in the foreground do you know that the user did not just launch your app through an alert or regularly from the home screen.
You can tell whether your app was just brought to the foreground or not in didReceiveRemoteNotification using this bit of code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateActive )
// app was already in the foreground
else
// app was just brought from background to foreground
...
}
You have to do several things in order to manage the received push notification when the app is in background.
First, in your server side, you have to set {"aps":{"content-available" : 1... / $body['aps']['content-available'] =1; in the push notification payload.
Second, in your Xcode project, yo have to habilitate "remote notifications". It is made by going to the project's target -> capabilities, then enable the capabilities switch, and check the remote notifications checkbox.
Third, instead of using didReceiveRemoteNotification, you have to call application:didReceiveRemoteNotification:fetchCompletionHandler:, this will allow you to do the tasks that you want in the background, at the moment of receiving the notification:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if(application.applicationState == UIApplicationStateInactive) {
NSLog(#"Inactive - the user has tapped in the notification when app was closed or in background");
//do some tasks
[self manageRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
else if (application.applicationState == UIApplicationStateBackground) {
NSLog(#"application Background - notification has arrived when app was in background");
NSString* contentAvailable = [NSString stringWithFormat:#"%#", [[userInfo valueForKey:#"aps"] valueForKey:#"content-available"]];
if([contentAvailable isEqualToString:#"1"]) {
// do tasks
[self manageRemoteNotification:userInfo];
NSLog(#"content-available is equal to 1");
completionHandler(UIBackgroundFetchResultNewData);
}
}
else {
NSLog(#"application Active - notication has arrived while app was opened");
//Show an in-app banner
//do tasks
[self manageRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
}
Finally, you have to add this notification type: UIRemoteNotificationTypeNewsstandContentAvailability to the notifications settings when you set it.
Apart from this, if your app was closed when the notification arrived, you have to manage this in didFinishLaunchingWithOptions , and just if the user taps on the push notification: The way of do it is:
if (launchOptions != nil)
{
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSLog(#"Launched from push notification: %#", dictionary);
[self manageRemoteNotification:dictionary];
}
}
launchOptions is != nil when you launch the app by tapping on the push notification, if you access it by tapping on the icon, launchOptions will be == nil.
I hope it will be useful. Here it is explained by Apple.
Pass content-available = 1 with your payload, and will invoke didReceiveRemoteNotification even in background. e.g.
{
"alert" : "",
"badge" : "0",
"content-available" : "1",
"sound" : ""
}
One thing to keep in mind, when your push message arrives at the user's iPhone and they click "cancel", except for the icon badge number (they'll be taken care of by the OS), there would be no way for your in-the-background app to know about this push event and take any further actions.
Word of warning
I think your app logic is basing behavior on custom data in your push notification. This is not what push notifications are intended for. What you should alternatively do on didbecomeactive in your application is just ask your server for the data you need and was sending as payload anyway, and rely on that instead of your payload.
Because the documentation also states that as best practice. Because Apple does not guarantee your push notification from being received 100% of the times anyway.
Important: Delivery of notifications is a “best effort”, not
guaranteed. It is not intended to deliver data to your app, only to
notify the user that there is new data available.
However, if you want to have some indication of whether for instance the badge has been changed without relying on a user opening the app by clicking on the badge you could something like this:
A. you add a (correct) badge number to the payload of the push notification sent by your server. It for instance could look like this:
{
"aps" : {
"alert" : "You got your emails.",
"badge" : 9
}
}
B. you keep track of that badge number persistently in your app, for instance by storing it in NSUserDefaults.
Then in applicationDidBecomeActive can compare the applicationIconBadgeNumber property of UIApplication with your previously stored badge count and see if it has been increased or decreased and do some updates based on that.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSNumber *badgecount = [[NSUserDefaults standardUserDefaults] objectForKey:#"badgecount"];
if (!badgecount) badgecount = #(0);
if ([UIApplication sharedApplication].applicationIconBadgeNumber != [badgecount integerValue]) {
//store the new badge count
badgecount = [NSNumber numberWithInteger:[UIApplication sharedApplication].applicationIconBadgeNumber];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:badgecount forKey:#"badgecount"];
[defaults synchronize];
// do some stuff here because it's different
}
}
As of recent iOS - I think 8 - if you've got remote notifications enabled as a background mode, one trick is to track whether you're entering the foreground as a flag.
#interface AppDelegate ()
#property (assign, atomic, getter=isEnteringForeground) BOOL enteringForeground;
#end
- (void) applicationWillEnterForeground: (UIApplication *) application
{
self.enteringForeground = YES;
}
- (void) applicationDidBecomeActive: (UIApplication *) application
{
self.enteringForeground = NO;
}
- (void) application: (UIApplication *) application didReceiveRemoteNotification: (NSDictionary *) userInfo fetchCompletionHandler: (void (^) (UIBackgroundFetchResult)) completionHandler
{
const BOOL launchedFromBackground = !(application.applicationState == UIApplicationStateActive);
const BOOL enteringForeground = self.enteringForeground;
if (launchedFromBackground && enteringForeground) {
// The user clicked a push while the app was in the BG
}
}