Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving Newsstand Notifications Only When App Is Running

i'm not receiving newsstand notifications when the app is not running, here is what I have done.

The app has the proper plist keys 'UINewsstandApp = YES' and 'UIBackgroundModes = newsstand-content'.

In the app delegate I register for all notification types, and i receive my token from APNS, from the server side ( i am using a gem called Grocer ) i set up the dev certificate and send a regular push and it works.

if i send a newsstand push I receive it if the app is running on 'didReceiveRemoteNotification', but when the app is not running i get nothing in the notification center, which is mainly because 'Grocer' has the following payload {"aps": {"content-available":1}} and can't add any other keys ( alert, badge, etc )

so I thought that I should not get anything in the notification center, I look for the 'UIApplicationLaunchOptionsRemoteNotificationKey' in the launch options, and then write a file to make sure that the app ran in the background, the file is never written as such

NSDictionary *remoteNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

if(remoteNotif)
    {
        NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *filePath = [cachePath stringByAppendingPathExtension:@"pushreceived.txt"];
        [@"testing" writeToFile:filePath atomically:YES encoding:NSASCIIStringEncoding error:nil];
    }

I have NKDontThrottleNewsstandContentNotifications set to true in my user defaults, and then I synchronize to make sure.

when the app is running, no matter how many times i send the push, I always get a callback on " didReceiveRemoteNotification ", with the proper "content-available"

if the app is closed or in the background, nothing happens.

Update:

I managed to change the gem that sends the notification payload, here is the dictionary it sends

{"aps"=>
   {
     "alert"=>"Hello iPhone!!",
     "content-available"=>1,
     "badge"=>1,
     "sound"=>"default"
   }
}

and here the userinfo dictionary I receive on my app ( while running )

{
    aps =     {
        alert = "Hello iPhone!!";
        badge = 1;
        "content-available" = 1;
        sound = default;
    };
}

please note the quotation marks around content-available, does this mean that APNS parsed it as a custom key ?

like image 660
Zoidberg Avatar asked Mar 03 '13 13:03

Zoidberg


1 Answers

To receive notifications when your application is running in the background, you need to add a applicationDidEnterBackgroud method to your main class. From the Apple documentation:

Applications might also find local notifications useful when they run in the background and some message, data, or other item arrives that might be of interest to the user. In this case, they should present the notification immediately using the UIApplication method presentLocalNotificationNow: (iOS gives an application a limited time to run in the background). Listing 2-2 illustrates how you might do this.


- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"Application entered background state.");
    // bgTask is instance variable
    NSAssert(self->bgTask == UIInvalidBackgroundTask, nil);

    bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [application endBackgroundTask:self->bgTask];
            self->bgTask = UIInvalidBackgroundTask;
        });
    }];

    dispatch_async(dispatch_get_main_queue(), ^{
        while ([application backgroundTimeRemaining] > 1.0) {

            // Replace this code with your notification handling process

            NSString *friend = [self checkForIncomingChat];
            if (friend) {
                UILocalNotification *localNotif = [[UILocalNotification alloc] init];
                if (localNotif) {
                    localNotif.alertBody = [NSString stringWithFormat:
                        NSLocalizedString(@"%@ has a message for you.", nil), friend];
                    localNotif.alertAction = NSLocalizedString(@"Read Message", nil);
                    localNotif.soundName = @"alarmsound.caf";
                    localNotif.applicationIconBadgeNumber = 1;
                    [application presentLocalNotificationNow:localNotif];
                    [localNotif release];
                    friend = nil;
                    break;
                }
            }
        }
        [application endBackgroundTask:self->bgTask];
        self->bgTask = UIInvalidBackgroundTask;
    });

}

Also note:

Because the only notification type supported for non-running applications is icon-badging, simply pass NSRemoteNotificationTypeBadge as the parameter of registerForRemoteNotificationTypes:.

like image 91
Michael Robinson Avatar answered Oct 17 '22 03:10

Michael Robinson