How to update the badge number in IOS push notific

2019-05-14 06:38发布

问题:

I recently use the Amazon SNS to push notification for my IOS app.

It works well, the only problem I have encountered is when I receive the notification , the badge number will not be updated, here is how I implement:

First I follow the example here https://aws.amazon.com/articles/9156883257507082 Here is the example code from the tutorial.

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    application.applicationIconBadgeNumber = 0;
    NSString *msg = [NSString stringWithFormat:@"%@", userInfo];
    NSLog(@"%@",msg);
    [[Constants universalAlertsWithTitle:@"Push Notification Received" andMessage:msg] show];
}


-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //Register for push notification
    application.applicationIconBadgeNumber = 0;
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    if(launchOptions!=nil){
        NSString *msg = [NSString stringWithFormat:@"%@", launchOptions];
        NSLog(@"%@",msg);
        [[Constants universalAlertsWithTitle:@"Push Notification Received" andMessage:msg] show];
    }

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    // Override point for customization after application launch.

    Message_BoardViewController *boardViewController = [Message_BoardViewController new];
    UINavigationController *navigationController = [UINavigationController new];

    navigationController.navigationBar.translucent = NO;

    [navigationController pushViewController:boardViewController animated:NO];
    [boardViewController release];

    self.window.rootViewController = navigationController;
    [navigationController release];

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];

    [self.window makeKeyAndVisible];

    // Logging Control - Do NOT use logging for non-development builds.
#ifdef DEBUG
    [AmazonLogger verboseLogging];
#else
    [AmazonLogger turnLoggingOff];
#endif

    [AmazonErrorHandler shouldNotThrowExceptions];

    return YES;
}

As you can see, from the tutorial code it state

application.applicationIconBadgeNumber = 0;

so obviously it will become 0 every time.

======================================================

I wonder what is the standard way to update the badge number?

Which appoarch is correct ?

1) Through programming like this application.applicationIconBadgeNumber = 0;

2) Or from the server payload like this?

    $body = array(
'alert' => $message,
'sound' => 'sound.caf',
'badge' => $badge_count // Should be int type
);

========================================================

However, I found there is obstacle for each apporach, for the 1), the didReceiveNotification is not fire when the app is at background , so I can not do something like application.applicationIconBadgeNumber++; to update the badge number.

for the 2) , the Amazon SNS service is only return

$body = array(
'alert' => $message,
); 

and simply how can the server knows the badge number and add it at server payload, it seems I still need to post the update badge number to Amazon in didReceiveNotification and add it to payload. But again, it does not call at background.

Sorry for new to IOS progamming, would some experience programmer kindly guide me to implement the badge number update with push notification? Thanks.

回答1:

You are supposed to send the badge number in the payload of the push notification. Your server should set the badge count. This way the badge count will be updated regardless of whether the app is running or not running (and regardless of whether the user taps the notification to open the app or not). Your server should know what number to send.

And as to how your server is supposed to know what badge number to send - I don't know your app's logic, but lets take an email application as an example - suppose you want the badge number to show how many unread messages exist. The app should notify the server whenever a message is read, so the server can maintain the correct badge number for each user. This way, even if the user has multiple ways to access the data (iPhone app, iPad app, desktop browser, etc...), the server would know the current badge count and each device would show the correct badge count.

The application.applicationIconBadgeNumber = 0 is meant to clear the badge once the application is opened. It should be done in both didReceiveRemoteNotification and didFinishLaunchingWithOptions, so that the badge number will always be cleared when the application is launched, or when the push notification is handled by the app.



回答2:

You can do something like this. Here I am using AWS Lambda and AWS SNS.

var params = {
'TargetArn' : 'Your Target Device',
'MessageStructure' : 'json',
'Message' : JSON.stringify({
  'default' : 'New Request from User',
  'APNS_SANDBOX' : JSON.stringify({
    'aps' : { 'alert' : 'New Request from User', 'badge':1,'category' : 'MESSAGE_CATEGORY' },
    'badge' : '1',
    'sound' : 'default',
    'attribute1' : "attribute 1 value",
    'attribute2' : "attribute 2 value",
    'attributeN' : "attribute N value"
  })
})
};

sns.publish(params, function(err, data) {
    if (err) {
        console.log(err.stack);
        return;
    }
    console.log('push sent');
    console.log(data);
    context.done(null, 'Function Finished!');  
});


回答3:

ok I figure out how to use the badge number with Amazon SNS, if you publish your notification with PHP, then you can implement the badge like this

                        $sns->publish(array(
                        'MessageStructure' => 'json',
                        'TargetArn' => $endpointArn,
                        'Message' => json_encode(array(
                            'APNS_SANDBOX' => json_encode(array(
                                'aps' => array(
                                    'alert' => $push_message,
                                    'badge' => 1
                                )
                            ))
                        )),
                    ));

Just don't forget to set the badge to zero at your appdelegate.m , in the onReceive, onLaunchwithoption and onCompletefromBackground (Can't remember the excat spelling)