track user choice for Push Notification [allow/don

2019-04-12 18:52发布

问题:

When an application need to register for push notification (UIApplication registerForRemoteNotificationTypes) a popup show Allow/Don't choice.

Is there a way to track when the user take this choice ?

Because the solution:

NSUInteger rntypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

is fine, but until the user touch something it's NO by default. I should only check this config after the user make a choice.

The consequence is that in my EasyAPNS server most of the application are in 'disabled' mode until the user relaunch them (because the second time the correct config will be pushed to my sever). So with the first launch the real choice of the user is probably not taken into account (if you accept really rapidly, before my app register to EasyAPNS then your choice is reflected back on the server at first launch)

Any idea ?

回答1:

There seems to be no way to determine whether the allow pop-up has been shown. I rely on user defaults to keep track of this:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    BOOL didRegisterForPush = [[NSUserDefaults standardUserDefaults] boolForKey:@"didRegisterForPush"];
    if (!didRegisterForPush) {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"didRegisterForPush"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    // .. send deviceToken to server
}

Now you can determine the authorization state using:

- (PushAuthorizationStatus)pushAuthorizationStatus
{
    UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
    if (types) {
        return kPushAuthorizationStatusAuthorized;
    }
    BOOL didRegisterForPush = [[NSUserDefaults standardUserDefaults] boolForKey:@"didRegisterForPush"];
    if (didRegisterForPush) {
        return kPushAuthorizationStatusDenied;
    }
    return kPushAuthorizationStatusNotDetermined;
}

Using this you can send the NotDetermined state to the server instead of Denied.



回答2:

Under iOS 8 and later the procedure is a little different. In iOS 8 the enabledRemoteNotificationTypes method was replaced by isRegisteredForRemoteNotifications.

However isRegisteredForRemoteNotifications always returns YES if the app attempted to register for notifications, regardless of whether the user actually allowed them or not.

To determine whether the user actually allowed notifications, use the function provided by @Lefteris here:

- (BOOL)pushNotificationsEnabled {
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)]) {
        UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
        return (types & UIUserNotificationTypeAlert);
    }
    else {
        UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
        return (types & UIRemoteNotificationTypeAlert);
    }
}