Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

like image 995
Erwin Avatar asked Feb 20 '11 11:02

Erwin


4 Answers

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
    ...
}
like image 141
Bogatyr Avatar answered Nov 17 '22 06:11

Bogatyr


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.

like image 19
AlbertoC Avatar answered Nov 17 '22 06:11

AlbertoC


Pass content-available = 1 with your payload, and will invoke didReceiveRemoteNotification even in background. e.g.

{
    "alert" : "",
    "badge" : "0",
    "content-available" : "1",
    "sound" : ""
}
like image 15
Sandeep Kumar Avatar answered Nov 17 '22 07:11

Sandeep Kumar


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.

like image 8
Di Wu Avatar answered Nov 17 '22 08:11

Di Wu