Is it possible to update application badge count by receiving a silent push.
When the application is not running in the background, this method is not called.
My guess is this method get called even if the app is not running in the background. Am I wrong?
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
int currentBadge = [UIApplication sharedApplication].applicationIconBadgeNumber;
DLog(#"%#, badge = %i", userInfo, currentBadge);
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + 1;
completionHandler(UIBackgroundFetchResultNoData);
}
I just want to increase badge number with any received notification. The notification payload do not have a "badge' field.
Is it possible?
And if the app does not run background, UIApplicationExitsOnSuspend = YES, I wonder in this situation will silent push work or not?
Related
I want to increase the badge count when a notification is received and decrease when user tap or open the app.
I also try this code but it doesn't work.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + 1;
}
As per my knowledge application is showing number as badge count which is sent by you in this { "aps" : { "badge" : 9 } } dictionary as badge value.
What you are setting in this method
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + 1;
}
is set when you open application by tapping on remote notification which is logically not write because when you are opening application that time you are setting badge count.
You must have to pass badge value in your aps dictionary and you may reset badge count when application opened (in didFinishLaunchingwithOption method).
Apart from this, there is no method you can write in your application code that set badge count as soon as you receive push notification and your application is already in kill mode(not open at all).
Is there a way in AppDelegate to get a queue of all the notification data? (Once the user opens the app).
As per apple documentation:
When a remote notification arrives, the system calls the application:didReceiveRemoteNotification:fetchCompletionHandler: method. Notifications usually signal the availability of new information. In your app delegate method, you might begin downloading new data from a server so that you can update your app’s data structures. You might also use the notification to update your user interface.
You have to enable remote notification background mode, only then you will get a callback to the above mentioned method.
Try this in your app delegate:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
For UILocalNotification, you can get received notifications by calling following function in your AppDelegate:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
}
}
If you want to find the list of local Notifications, that app has already set, check this solution.
You can check for launchOptions Dictionary, for received Notification, when App resumes on tapping a notification,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
NSLog(#"Launch Options:%#",launchOptions);
return YES;
}
This question already has answers here:
Remote notification method called twice
(2 answers)
Closed 7 years ago.
I am trying to implement APNs in my app with the content-available key so that a background refresh will be triggered. Here is my code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
if([userInfo[#"aps"][#"content-available"] intValue]== 1){
//This stops a refresh happening is a push is delivered with the app in the foreground
if(application.applicationState!=UIApplicationStateActive){
NSLog(#“Background push refresh called");
[self backgroundRefreshWithPushUpdate:NO andHandler:^(BOOL successful, BOOL newMessages) {
if(successful){
if(newMessages) handler(UIBackgroundFetchResultNewData);
else handler(UIBackgroundFetchResultNoData);
}
else{
handler(UIBackgroundFetchResultFailed);
}
}];
}
else handler(UIBackgroundFetchResultNoData);
}
}
I have this additional condition: if(application.applicationState!=UIApplicationStateActive) for refreshing in the background as I don't want it to be triggered if the app is in the foreground. However, if I receive a push and then tap on the notification to open the app ALL of the code in - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler is called again. This means my background fetch is called when the notification first comes in and then it's called again when the notification is tapped on. I don't want this to happen. Any ideas how I can get around this?
Here are the things to be noticed in application:didReceiveRemoteNotification:fetchCompletionHandler: method when you receive a push notification:1. When the app is not launched (i.e, when the app is neither in background nor in foreground), the method is called once and applicationState will be UIApplicationStateInactive.2. When the app is in foreground, the method is called once and applicationState will be UIApplicationStateActive.3. When the app is in background, the method is called twice, once when you receive the push notification, and other time when you tap on that notification. When you receive the push notification, applicationState will be UIApplicationStateBackground and when you tap on that notification, applicationState will be UIApplicationStateInactive.We can ignore it when the applicationState will be UIApplicationStateBackground and hence we can handle the push notification only once for all the three scenarios.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if (application.applicationState == UIApplicationStateBackground) {
completionHandler(UIBackgroundFetchResultNoData);
return;
}
// Do whatever you need here and call completionHandler with appropriate UIBackgroundFetchResult
}
In my application I have two types of push notifications: remote silent notifications with content-available = 1 flag and usual push notifications with body, badge and other stuff.
I also define two delegate methods didReceiveRemoteNotification:fetchCompletionHandler and usual didReceiveRemoteNotification.
But when a push-notification without content-available flag arrives didReceiveRemoteNotification:fetchCompletionHandler is called, instead of didReceiveRemoteNotification.
How to fix this?
Why can't I have two delegate methods for background and usual pushes?
iOS 7 only calls the new one, this is how I handled it in my app:
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// Pass on
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:nil];
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// Check if in background
if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive) {
// User opened the push notification
} else {
// User hasn't opened it, this was a silent update
}
}
I want to clear all push notifications of my application, once user selects one of the push notification.
I have seen other threads here which says it's not possible in iOS.
but I have one application downloaded from app store, which does the same thing.
If it is a local notification then to remove badge icon you have to do it like this
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.applicationIconBadgeNumber = 1;
If it is push notification the you can do it by code written below
[UIApplication sharedApplication].applicationIconBadgeNumber=0;
You may call these methods anywhere you want. For example if you want to clear notification at the moment when the app is launched then write it in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
if your app doesn't use the badge number you have to first set, then reset it to remove it from notification centre.
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
All you need to do is
application.applicationIconBadgeNumber = 0;
in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions.
EDIT
If you are not closing your app but just sending it to background. Then add this in your below function as well.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground )
{
//opened from a push notification when the app was on background
application.applicationIconBadgeNumber = 0;
}
}