For silent push notification I have implemented this method :
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
if([userInfo[#"aps"][#"content-available"] intValue]== 1) //it's the silent notification
{
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
// CASE - 1
if (state == UIApplicationStateBackground )
{
//Badge increment
}
// CASE -2 for foreground
else {
//Badge increment
}
handler(UIBackgroundFetchResultNewData);
return;
}
Two scenario
1) I want to decrease the badge count when user clicks the notification .(app comes to foreground)
2) and take no action in badge when notification arrives while (app is in foreground ).
But for both the scenarios , same code is executed . And badge decrement occurs . (Commented as CASE - 2).
How to act according to these scenarios .
Related
An app is running on iPhone and user tap the home button once and app will enter background.
after 2 or 3 seconds local notification arrives and user tap on local notification.
app will again enter in foreground and become active and didReceiveLocalNotification will be called.
How to determine that app become active by tapping on local notification not the app icon.
Here is an easy way to detect what's your App's status when UILocalNotification fired and if
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
is called, this makes sure that local notification is received.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
} else {
}
}
I am working on push notifications and the data I receive is in JSON format. How can I parse the JSON data, which is shown in the Notification Center below:
if your app in background/foreground mode call this method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
if you used the above method you will face the following error in console
application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist.
To Resolve this issue
follow the image of steps
if your app in foreground mode call this method
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
choice no-2
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIApplicationState state = [application applicationState];
// user tapped notification while app was in background
if (state == UIApplicationStateInactive || state == UIApplicationStateBackground) {
// go to screen relevant to Notification content
} else {
// App is in UIApplicationStateActive (running in foreground)
// perhaps show an UIAlertView
}
}
Swift
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
var state: UIApplicationState = application.applicationState()
// user tapped notification while app was in background
if state == .Inactive || state == .Background {
// go to screen relevant to Notification content
}
else {
// App is in UIApplicationStateActive (running in foreground)
// perhaps show an UIAlertView
}
}
If didReceiveRemoteNotification method is not called in background mode,please follow the below steps
First ON the Push Notification and Tick the check box of Remote Notifications of Background Mode in Capabilities of Target
Then
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void
(^)(UIBackgroundFetchResult))completionHandler
{
if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive )
{
NSLog( #"INACTIVE" );
}
else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground )
{
NSLog( #"BACKGROUND" );
}
else
{
NSLog( #"FOREGROUND" );
}
return YES;
}
I know you can use this code for handling your notifications :
- (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
}
}
But this isn't reliable it does loops with number of current notifications so it shows my view controller hundres of time
So my question is :
is there any other "good" way we can use it to handle only the tapped notification ?
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
}
}