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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With