iOS 8 enabled device not receiving PUSH notifications after code update

51,591

Solution 1

The way to register for push notifications has been changed in iOS 8: Below is the code for all versions till iOS 9:

if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)])
{
    [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

}
else
{
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}

In case you want to check whether push notifications are enabled or not use below code:

- (BOOL) pushNotificationOnOrOff
{
    if ([UIApplication instancesRespondToSelector:@selector(isRegisteredForRemoteNotifications)]) {
        return ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]);
    } else {
        UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
        return (types & UIRemoteNotificationTypeAlert);
    }
}

#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application   didRegisterUserNotificationSettings:   (UIUserNotificationSettings *)notificationSettings
{
    //register to receive notifications
    [application registerForRemoteNotifications];
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString   *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
    else if ([identifier isEqualToString:@"answerAction"]){
    }
}
#endif

Above code will run on Xcode 6+ only...

Solution 2

Add this line at the top of your .m file

 #define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

1) You have to put condition when you register for push notification in IOS8. add this code in application did finish launch.

if(IS_IOS_8_OR_LATER) {
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: (UIRemoteNotificationTypeBadge
                                                                                         |UIRemoteNotificationTypeSound
                                                                                       |UIRemoteNotificationTypeAlert) categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
 } else {
    //register to receive notifications
    UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
 }

2) Then add this methods for IOS8

#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:   (UIUserNotificationSettings *)notificationSettings
{
    //register to receive notifications
    [application registerForRemoteNotifications];
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString   *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
    else if ([identifier isEqualToString:@"answerAction"]){
    }
}
#endif

Then you notification delegate method will be called. hope this will help you !!!

Solution 3

if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // For iOS 8

[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

 [[UIApplication sharedApplication] registerForRemoteNotifications];
} 

else 
{
    // For iOS < 8
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}

After this:

  1. Delete the apps who don't have Push notifications any more form the device.
  2. Turn the device off completely and turn it back on.
  3. Go to settings and set date and time ahead a day
  4. Turn the device off again and turn it back
  5. Install the apps again and It'll ask for notification like the first time you installed It.
  6. Reset your date / time again if not automatically set.

This will reset the notification settings. Re install the app and all will work fine :)

Solution 4

Runtime and old compiler safe options ... if you run in old xcode (5.0 or earlier)

    // changes of API in iOS 8.0
- (void) registerForPushNotification
{
    NSLog(@"registerForPushNotification");
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 //__IPHONE_8_0 is not defined in old xcode (==0). Then use 80000

        NSLog(@"registerForPushNotification: For iOS >= 8.0");

        [[UIApplication sharedApplication] registerUserNotificationSettings:
            [UIUserNotificationSettings settingsForTypes:
                (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
                                              categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
#endif
    } else {
        NSLog(@"registerForPushNotification: For iOS < 8.0");
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
    }
}

Solution 5

Its very simple:

Add following line in didFinishLaunchingWithOptions of your project in xcode6

 [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
 [[UIApplication sharedApplication] registerForRemoteNotifications];
Share:
51,591
Zigglzworth
Author by

Zigglzworth

Swimming around in my imagination...enjoying it... gonna stay here for a while

Updated on October 10, 2020

Comments

  • Zigglzworth
    Zigglzworth over 3 years

    I recently upgraded one of my test iphones to iOS 8 and then upgraded the PUSH registration code as below (using xCode 6)

    -(BOOL)hasNotificationsEnabled {
    
        NSString *iOSversion = [[UIDevice currentDevice] systemVersion];
        NSString *prefix = [[iOSversion componentsSeparatedByString:@"."] firstObject];
        float versionVal = [prefix floatValue];
    
    
        if (versionVal >= 8)
        {
    
            NSLog(@"%@", [[UIApplication sharedApplication]  currentUserNotificationSettings]);
            //The output of this log shows that the app is registered for PUSH so should receive them
    
            if ([[UIApplication sharedApplication] currentUserNotificationSettings].types != UIUserNotificationTypeNone) {
    
                return YES;
    
            }
    
        }
        else
        {
            UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
            if (types != UIRemoteNotificationTypeNone){
                return YES;
            }
    
        }
    
        return NO;
    }
    
    -(void)registerForPUSHNotifications {
    
        NSString *iOSversion = [[UIDevice currentDevice] systemVersion];
        NSString *prefix = [[iOSversion componentsSeparatedByString:@"."] firstObject];
        float versionVal = [prefix floatValue];
    
    
        if (versionVal >= 8)
        {
    
    
                //for iOS8
            UIUserNotificationSettings *settings =
            [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
             UIUserNotificationTypeBadge |
             UIUserNotificationTypeSound categories:nil];
            [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
            [[UIApplication sharedApplication] registerForRemoteNotifications];
    
    
        }
        else
        {
    
                [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    
    
        }
    }
    

    Despite this upgrade and the fact that [[UIApplication sharedApplication] currentUserNotificationSettings] shows PUSH is enabled for the device, I am not receiving PUSH notifications.

    I am using Parse and doing everything by the book as far as they are concerned ( https://parse.com/tutorials/ios-push-notifications) .

    Is anyone experiencing the same issue? Is there something else that I may be missing ?

  • Michal Shatz
    Michal Shatz over 9 years
    types & UIUserNotificationTypeAlert return false either way on iOS8
  • Kevin
    Kevin over 9 years
    The check should really use respondsToSelector, not the OS version.
  • Kevin
    Kevin over 9 years
    Using this method only works if you distribute for one OS version only. If you set your base version to 7 and distribution target to 8, this will crash on iOS 7; if you set your distribution target to 7, it won't work on 8. The correct method is a runtime check, as in penkaj's answer (though that currently uses the wrong runtime check, see my comment on it).
  • Nits007ak
    Nits007ak over 9 years
    yeah ok you can put if else condition then no issue. Thanx!!
  • Nits007ak
    Nits007ak over 9 years
    I edited the code now it will work for ios7 as well and yeah you have to add those old delegate methods of remote notification for below IOS8 to get callback whenever any push arrives.
  • karim
    karim over 9 years
    The answer could be wrong. in the 'else', it should be, UIRemoteNotificationTypeXXXXX instead of UIUserNotificationType****. UIUserNotificationType**** is not defined in earlier iOS'es and will crash the app.
  • Pankaj Wadhwa
    Pankaj Wadhwa over 9 years
    well @karim its 100% tested code and its work great.. I couldn't understand how people can down vote the answers without testing themselves.So its better to test first before down voting someone's answer... And for your kind information my app is live and push notifications are working on iOS 8 and before versions too.
  • karim
    karim over 9 years
    Well, you know UIUserNotificationTypeBadge and so on are defined iOS 8.0. So xcode 5 will have compiler error. However, since its a constant it will work runtime in the devices less than 8.0. Its better to use old constants, [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationType‌​Alert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
  • Pankaj Wadhwa
    Pankaj Wadhwa over 9 years
    @karim hahaha people usually are. Well in answer's context i would like to say that best practice is to dump older stuff and adopt the newer one and would suggest you to do the same rather than down voting others answers for no stupid/no reasons.
  • Developer
    Developer over 9 years
    @pankajwadhwa But I am getting compile time error for "registerUserNotificationSettings". How can I create a build?
  • Pankaj Wadhwa
    Pankaj Wadhwa over 9 years
    @Developer make sure you are on Xcode 6. it's not suppose to give any type of error on Xcode 6.
  • Pankaj Wadhwa
    Pankaj Wadhwa over 9 years
    @Developer if you are on Xcode 6 and getting error then deleting derived data may do the trick...
  • Developer
    Developer over 9 years
    Its fixed now! Thanks!
  • Pankaj Wadhwa
    Pankaj Wadhwa over 9 years
    @Developer what was the problem??
  • Developer
    Developer over 9 years
    This was the main issue: stackoverflow.com/questions/26366453/… But when I uploaded the build with XCode 6.0.1, it worked. Still surprised why it didn't work with XCode 6.1(Not Beta)
  • tesmojones
    tesmojones over 9 years
    @Nits007ak, did you test push on real device ios 7?
  • Nits007ak
    Nits007ak over 9 years
    @tesmojones yes I test its working fine...u need to add old delegate methods of remote notification didRegisterForRemoteNotificationsWithDeviceToken, didReceiveRemoteNotification for below IOS8
  • Muzammil
    Muzammil over 9 years
    After above, follow these steps to reset notification setting: 1. Delete the apps who don't have Push notifications any more form the device. 2. Turn the device off completely and turn it back on. 3. Go to settings and set date and time ahead a day 4. Turn the device off again et turn it back 5. Install the apps again and It'll ask for notification like the first time you installed It. This will reset the notification settings.
  • Daniel Galasko
    Daniel Galasko over 9 years
    The documentation says that you should only call registerForRemoteNotifications once didRegisterUserNotificationSettings is called
  • mattsven
    mattsven over 8 years
    Thank you! I was having problems with the notification prompt, this fixed it.