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 ?
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
.
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);
}
}