1

My iOS app stopped receiving push notifications although I upgraded the code as per the documentations and this.

Here's the code I'm using:

In my AppDelegate's didFinishLaunchingWithOptions:

if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {

    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
     UIUserNotificationTypeBadge | UIUserNotificationTypeSound  categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
}
else {
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert |
     UIRemoteNotificationTypeBadge |
     UIRemoteNotificationTypeSound];
}

The didRegisterForRemoteNotificationsWithDeviceToken method is getting called, as it was before, so everything seems fine.

Also, my test device has the notifications enabled.

But when sending a push from Parse.com it no longer arrives.

EDIT 1:

None of the answers work. I updated my Parse.com framework to version 1.6.2 (the latest) which doesn't help either, and I'm copying my code again - this time the updated version based on the answers:

Inside didFinishLaunchingWithOptions:

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
                                                                                         |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert) categories:nil];
    [application registerUserNotificationSettings:settings];
    //        [application registerForRemoteNotifications];
} else {
    UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
    [application registerForRemoteNotificationTypes:myTypes];
}

And these are the delegate methods:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken {
    NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken CALLED");

    // Store the deviceToken in the current installation and save it to Parse.
    PFInstallation *currentInstallation = [PFInstallation currentInstallation];
    [currentInstallation setDeviceTokenFromData:newDeviceToken];
    [currentInstallation addUniqueObject:@"Test8Channel" forKey:@"channels"];

    if([PFUser currentUser]/* && [[PFUser currentUser] objectId] != nil*/) {
        [currentInstallation addUniqueObject:[PFUser currentUser] forKey:kOwnerKey];
    }
    [currentInstallation saveInBackground];

}

#ifdef IS_OS_8_OR_LATER
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
    NSLog(@"didRegisterUserNotificationSettings CALLED");
}

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


- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    if (error.code == 3010) {
        NSLog(@"Push notifications are not supported in the iOS Simulator.");
    } else {
        // show some alert or otherwise handle the failure to register.
        NSLog(@"application:didFailToRegisterForRemoteNotificationsWithError: %@", error);
    }
}

Both didRegisterUserNotificationSettings and didRegisterForRemoteNotificationsWithDeviceToken are getting called and it seems fine. But the push doesn't arrive.

EDIT 2:

I'm noticing that if I call both

[application registerUserNotificationSettings:settings];

and

[application registerForRemoteNotifications];

inside the if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {

the delegate's didRegisterForRemoteNotificationsWithDeviceToken is getting called twice. I'm not sure how meaningful this is.

Getting desperate here.

Community
  • 1
  • 1
Eddy
  • 3,533
  • 13
  • 59
  • 89
  • how are you sending from the console i.e, plain text/json? and are you waiting to receive it will in background or foreground? – soulshined Jan 25 '15 at 11:11
  • I'm taking the default, which is plain text, and I've tried both in the background and foreground. I also put a printf in the didReceiveRemoteNotification method but it's not getting called. – Eddy Jan 25 '15 at 11:47
  • And the provisioning profiles or certificates haven't been altered? – soulshined Jan 25 '15 at 12:04
  • No, nothing changed. – Eddy Jan 25 '15 at 12:12
  • Just wanna do a quick check. while going to background, check result of [[UIApplication sharedApplication] isRegisteredForRemoteNotifications]; and let know the result. – bllakjakk Feb 01 '15 at 11:23
  • It's 1. Thanks for responding, @bllakjakk – Eddy Feb 01 '15 at 12:01

3 Answers3

0
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self enableNotifications:application];
    return YES;
}


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

- (void)enableNotifications:(UIApplication *)application
{
    if (iOS8_OR_NEWER) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:nil];
        [application registerUserNotificationSettings:settings];
        [application registerForRemoteNotifications];
    } else {
        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    }
}

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

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
    // https://nrj.io/simple-interactive-notifications-in-ios-8
}
#endif

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSLog(@"Push Token : %@", deviceToken);
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"Failed to get token, error: %@", error);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    NSLog(@"didReceiveRemoteNotification : %@", userInfo);
}
emotality
  • 12,795
  • 4
  • 39
  • 60
  • I edited the question to reflect the code after the advice here. It's still not working. – Eddy Feb 05 '15 at 10:44
  • There must be something wrong, if you try the above code on a different Xcode and still not works it's definitely the device? Have you tried different devices? The above is the only code I got and works 100%. Every time I start my app all the methods are being called. – emotality Feb 06 '15 at 18:26
0
    //-- Set Notification
    if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
    {
        // iOS 8 Notifications
        [application  registerUserNotificationSettings:[UIUserNotificationSettings  settingsForTypes:(UIUserNotificationTypeSound |  UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)  categories:nil]];
        [application registerForRemoteNotifications];
    }
    else
    {
        // iOS < 8 Notifications
        [application registerForRemoteNotificationTypes:
         (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }
RaviM
  • 62
  • 14
  • I edited the question to reflect the code after the advice here. It's still not working. – Eddy Feb 05 '15 at 10:43
0

Use this simple conditional block for handle it. because some methods/classes are updated with version

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
    //ios8
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)])
    {
        
        UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        
        [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
        
        .......
    }
}
else
{
    // ios7
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerForRemoteNotificationTypes:)])
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
      .........
    }
}
Community
  • 1
  • 1
Sarat Patel
  • 856
  • 13
  • 32
  • "conditional block" It's definitely not a block, and a block isn't even necessary in this case. And your answer is exactly the same as all the other answers, just 10 times more code... – emotality Feb 22 '15 at 04:15