3
votes

I have seen too many questions about the silent push notification does not work if the device is not connected to xcode, but I could not find the real answer. I'm using Silent APN to start a process in background and then fire a local Push notification

  1. Server sends this info:

    "_metadata" =     {
        bagde = 1;
        pushText = "semeone has sent you a message!!";
        sender = "semeone";
    };
    aps =     {
        "content-available" = 1;
    };
    

    And _metadata is customized info to fire the local notification, I did not included badge, pushText.. in aps because I it is a silent push notification.

  2. Client should get the info in didReceiveRemoteNotification,

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
    if(application.applicationState != UIApplicationStateActive ){
            if([userInfo[@"aps"][@"content-available"] intValue]== 1) //it's the silent notification
            {
                //start a background task 
                UIBackgroundTaskIdentifier preLoadPNTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
                    NSLog(@"Background task to start a process ");
                }];
                //end completionHandler regarding to fetchCompletionHandler
                completionHandler(UIBackgroundFetchResultNewData);
    
                // doing my process...... and fire a local notification
    
                if(preLoadPNTask){
                    NSLog(@"End Background task ");
                    [[UIApplication sharedApplication] endBackgroundTask:preLoadPNTask];
                    preLoadPNTask = 0;
                }
                return;
            }
            else
            {
                NSLog(@"didReceiveRemoteNotification it's NOT the silent notification ");
                completionHandler(UIBackgroundFetchResultNoData);
                return;
            }
    
        }
    else {
        if(preLoadPNTask){
            NSLog(@"End Background task ");
            [[UIApplication sharedApplication] endBackgroundTask:preLoadPNTask];
            preLoadPNTask = 0;
        }
        completionHandler(UIBackgroundFetchResultNewData);
    }
    
    }
    

It works perfectly fine when the device is connecting to xcode, but when it doesn't, the didReceiveRemoteNotification doesn't start :(

Any ideas?

Thank you in advance!!

3
What task are you performing when the notification is received? - Fawad Masud
I'm adding to NSMutableDictionary the ID and the sender, then I sent data to Worklight [[WL sharedInstance] sendActionToJS:@"silentNotification" withData:dictionary]; and then I release the Local notification localNotif.soundName = UILocalNotificationDefaultSoundName; localNotif.applicationIconBadgeNumber = badge; localNotif.alertBody = textAlert; localNotif.userInfo = userInfoData; [[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; [localNotif release]; - Jan
how do you know if the didReceiveRemoteNotification method is called? - Fawad Masud
I have encountered the same situation with you @jan. Can't solve it so far. (iOS 8.1.2) - Santana
I have tested this on iOS 7 and iOS 8 devices. I have encountered the same issue with iOS 8 devices and couldn't figure out what was going on. On my iOS 7 device, everything works -- silent notifications are received (with or without xcode). On my iOS 8 device, silent notifications are not received at all (without Xcode). It works 100% with Xcode though. If any of you find a solution, please let me know. - Sandy D.

3 Answers

0
votes

What I end up is a cable USB was cause me some issues apparently every time that I plugged in the iphone device said that "this accessory may not be supported" but it continue working normally , so I replace for a new one, but that not solve my issue, however can be part of this. so I looked in the code, and I did some changes, after receive 2 o more silent push notification preLoadPNTask (UIBackgroundTaskIdentifier) was creating many times so I added a validation before it start,

if(!preLoadPNTask){
//start a background task 
            UIBackgroundTaskIdentifier preLoadPNTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
                NSLog(@"Background task to start a process ");
            }];

 }

I hope this help you Regards

0
votes

In ios 8, You need to the following steps to fire didReceiveRemoteNotification: method

  1. Select project target goto Capabilities tab
  2. Select 'Background modes' turn on.
  3. It'll add a key (Required background modes)in your project info.plist

After these modifications, when you get a apple push notification and if the app is in background already then didReceiveRemoteNotification will be fired.

0
votes

Probably because under iOS 8 you have to ask for push notifications in a different way. Try this:

-(void) registerForPushNotifications {

UIApplication* application=[UIApplication sharedApplication] ;

// Register for Push Notitications, if running iOS 8
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];
    [application registerUserNotificationSettings:settings];
    [application registerForRemoteNotifications];

} else {
    // Register for Push Notifications before iOS 8
    [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}

}