Remote Notification Token handling

2019-04-14 02:17发布

问题:

I'm registering my iPhone application for Remote Notification.

Here my scenario:

  1. User opens my app and register for remote notification
  2. User turns notification off for my app
  3. User open my app
  4. User turns notification on for my app

My questions are:

  1. Is it possible to check if the user has disabled remote notification for my app inside my app's code?
  2. If I request a new token without user turn off notification for my app, the retrieved token is different or is always the same?
  3. Should I request a new token every time I start my app?

回答1:

So you want to know about UIRemoteNotifications? :) Cool, because they're not really as complex as people often make them out to be. Though, I am going to address your questions in reverse order. It flows better than way.

Your questions:

Should I request a new token every time I start my app?

Sort of. With UIRemoteNotifications, you never really request a token, so much as request permission and receive a token. What you should do is implement application:didRegisterForRemoteNotificationsWithDeviceToken: in your app delegate. This method (along with its error-catching sibling application:didFailToRegisterForRemoteNotificationsWithError:) is the callback for registerForRemoteNotificationTypes:. It's best practice to call registerForRemoteNotificationTypes: during application:didFinishLaunchingWithOptions:. (Don't worry about all of the method names flying around. I'll explain codewise shortly).

If I request a new token without user turn off notification for my app, the retrieved token is different or is always the same?

Maybe. The device token is subject to change for security reasons, but in general you shouldn't need to be too concerned with it changing.

Is it possible to check if the user has disabled remote notification for my app inside my app's code?

Why, yes it is. UIApplicationDelegate has a method called enabledRemoteNotificationTypes, which gets all of the remote notification types requested by you and enabled by your user. More on that shortly.

Putting it all together:

At the end of the day, you should end up with something like this:

#define deviceTokenKey   @"devtok"
#define remoteNotifTypes UIRemoteNotificationTypeBadge | \
                         UIRemoteNotificationTypeAlert

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    //generic setup and whatnot

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: remoteNotifTypes];
    if (([[NSUserDefaults standardUserDefaults] stringForKey: deviceTokenKey]) &&
        ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] != remoteNotifTypes))
    {
        //user has probably disabled push. react accordingly.
    }
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token
{    
    NSString *deviceToken = [token description];
    deviceToken = [deviceToken stringByReplacingOccurrencesOfString: @"<" withString: @""];
    deviceToken = [deviceToken stringByReplacingOccurrencesOfString: @">" withString: @""];
    deviceToken = [deviceToken stringByReplacingOccurrencesOfString: @" " withString: @""];

    if ([[NSUserDefaults standardUserDefaults] stringForKey: deviceTokenKey])
    {
        if (![[[NSUserDefaults standardUserDefaults] stringForKey: deviceTokenKey] isEqualToString: deviceToken])
        {
            [[NSUserDefaults standardUserDefaults] setObject: deviceToken forKey: deviceTokenKey];
            [[NSUserDefaults standardUserDefaults] synchronize];

            //user allowed push. react accordingly.
        }
    }
    else
    {
        [[NSUserDefaults standardUserDefaults] setObject: deviceToken forKey: deviceTokenKey];
        [[NSUserDefaults standardUserDefaults] synchronize];

        //user allowed push. react accordingly.
    }
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog("application: %@ didFailToRegisterForRemoteNotificationsWithError: %@", application, [error localizedDescription]);
}


回答2:

  1. I'm not sure you can, I guess if user has disabled remote notification, the notification will still be sent to user's device, but it will not be displayed.

2. The retrieved token can be changed according to this SO.

3. Yes, in case the token changes.