Is is possible to detect when a device's mobile push registration token has been invalidated?

An often overlooked best practice when implementing Apple Push Notifications (APN) in your iOS applications is verifying that the registration token has not become invalid with each cold start of the app. A cold start happens when application didFinishLaunching is called (the actual method name is longer and spelled out in the docs linked below).

Here's the outline of what we need to do:

  • Call registerForRemoteNotification in didFinishLaunching. This will ask APNS for the registration token. The response is handled in `application didRegisterForRemoteNotificationsWithDeviceToken'.
  • In didRegisterForRemoteNotifications, you will receive the registration token.
  • Check for the current registration token in NSUserDefault.
  • If the registration token from NSUserDefault is nil or not equal to the registration token that was just passed into didRegisterForRemoteNotifications, then...
    • register for push notifications with PubNub using the new registration token
    • save the new registration token in NSUserDefault
  • Otherwise, the registration token has not changed (is still valid), and you do not need to do anything further (you are already registered for push notifications on PubNub channels from the last cold start of the app).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    PubNub *pubNub = [PubNub clientWithConfiguration:[
        PNConfiguration configurationWithPublishKey:@"pub-c-..." 
                                        subscribeKey:@"sub-c-..."]
    ];

    self.client = pubNub;

    UIUserNotificationType types = UIUserNotificationTypeBadge |
        UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

    UIUserNotificationSettings *mySettings =
        [UIUserNotificationSettings settingsForTypes:types categories:nil];

    // In iOS 8, this is when the user receives a system prompt for notifications in your app
    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];

    return YES;
}

- (void)application:(UIApplication *)application 
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        NSLog(@"deviceToken: %@", deviceToken);
        NSData *oldToken = [[NSUserDefaults standardUserDefaults] dataForKey:@"DeviceToken"];

        if (oldToken && [oldToken isEqualToData:deviceToken]) {
            // registration token hasn't changed - carry on
            return;
        }

        // remove old token from all PubNub channels for push notifications
        [self.client removeAllPushNotificationsFromDeviceWithPushToken:self.devicePushToken
            andCompletion:^(PNAcknowledgmentStatus *status) {
                NSLog(@"status: %@", status);
                // Check whether request successfully completed or not.
                // if (status.isError) // Handle modification error. 
                //     Check 'category' property to find out possible issue because
                //     of which request did fail. Request can be resent using: [status retry];
            }
        ];

        [self.client addPushNotificationsOnChannels:@[<array of channels here>] 
            withDevicePushToken:deviceToken andCompletion:^(PNAcknowledgmentStatus *status) {
                NSLog(@"status: %@", status);
                [[NSUserDefaults standardUserDefaults] setObject:deviceToken forKey:@"DeviceToken"];
                // Check whether request successfully completed or not.
                // if (status.isError) // Handle modification error. 
                //     Check 'category' property to find out possible issue because
                //     of which request did fail. Request can be resent using: [status retry];
            }
            }
        ];
}

For more details (but less precise code example), please review the the PubNub iOS SDK Mobile Push Gateway documentation.

Summary

The idea is to always check the validity of the APNS registration token with every cold start of the app, but only update PubNub's mobile push registration when the registration token actually changes for that device.