DidReceiveRemoteNotification when in the background

This question has been asked several times, but I have a certain situation.

When my application is active and I receive a PUSH message, I can successfully analyze user payloads, etc.

However, when my application is in the background and PUSH arrives, the user must click the Open / Open button to receive a call to didReceiveRemoteNotification and then didFinishLaunchingWithOptions is didFinishLaunchingWithOptions .

I need my application to decide whether to request a UIAlert user in the background or suppress a push message based on some local settings.

Any help would be appreciated

+49
iphone ios4 apple-push-notifications
Feb 20 '11 at 11:21
source share
6 answers

The application should handle all possible push notification delivery states:

  • Your application has just started

  • Your application was simply moved from the background to the foreground

  • Your application has already been launched in the foreground

You cannot choose the delivery time, which presentation method is used to present the push notification that is encoded in the notification itself (additional warning, icon number, sound). But since you are apparently controlling both the application and the payload of the push notification, you can indicate in the payload whether or not there was a warning and a message already presented to the user. Only if the application is already running in the foreground, you know that the user did not just launch the application through a warning or regularly from the main screen.

You can determine if your application was simply brought to the forefront 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 ... } 
+147
Feb 20 '11 at 12:12
source share

Pass content-available = 1 with your payload and call didReceiveRemoteNotification even in the background. eg.

 { "alert" : "", "badge" : "0", "content-available" : "1", "sound" : "" } 
+13
Dec 30 '15 at 15:21
source share

You have to do a few things to manage the push notifications received when the application is in the background.

Firstly, on your server side you should set {"aps":{"content-available": 1.../$body['aps']['content-available'] =1; in the useful data of push notifications.

Secondly, in your Xcode project you need to provide "remote notifications." This is done by going to the project goal → features, then turning on the features switch and checking the remote notifications flag.

Thirdly, instead of using didReceiveRemoteNotification you should call application:didReceiveRemoteNotification:fetchCompletionHandler: this will allow you to perform the tasks that you want in the background at the time you receive 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 should add this type of notification: UIRemoteNotificationTypeNewsstandContentAvailability to the notification settings when it is installed.

In addition, if your application was closed when a notification arrived, you should manage it in didFinishLaunchingWithOptions , and only if the user clicks on the push notification: a way to do this:

 if (launchOptions != nil) { NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; if (dictionary != nil) { NSLog(@"Launched from push notification: %@", dictionary); [self manageRemoteNotification:dictionary]; } } 

LaunchOptions parameter matters! = nil, when you launch the application by clicking on the push notification, if you get access to it by clicking on the icon, launchOptions will == nil.

Hope this will be helpful. This is explained by Apple .

+11
Jan 15 '16 at 13:28
source share

One thing to keep in mind when your push message arrives on the user's iPhone and they click cancel, except for the icon icon number (the OS will take care of it), there would be no way for your application in the background. to learn about this push event and take further action.

+7
Feb 20 '11 at 12:10
source share

Warning word

I think your application logic bases the behavior on user data in your push notification. This is not what is meant for push notifications. What you should alternatively do on didbecomeactive in your application is to simply ask your server about the data you need and in any case send it as a payload, and rely on it instead of your payload.

Because the documentation also says that this is best practice. Because Apple does not guarantee that your push notification will be received 100% of the time in any case.

Important: notification delivery is a "best effort", not guaranteed. It is not intended to deliver data to your application, only to notify the user about the availability of new data.

However, if you want to know if the icon has been changed without relying on the user opening the application by clicking the icon, you could have something like this:

A. you add the (correct) icon number to the payload of the push notification sent by your server. For example, it might look like this:

 { "aps" : { "alert" : "You got your emails.", "badge" : 9 } } 

B. you constantly keep track of this icon number in your application, for example by storing it in NSUserDefaults .

Then in applicationDidBecomeActive you can compare the applicationIconBadgeNumber UIApplication property with your previously saved number of icons and see if it has been increased or decreased, and make some updates based on this.

  - (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 different } } 
+2
Aug 05 '14 at 3:15
source share

Recently, iOS - I think 8 - if you have remote notifications as a background, one trick is to keep track of whether you enter 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 } } 
0
Apr 6 '16 at 21:37
source share



All Articles