The solution that I've found is a bit of a hack, but it works.
You need to call registerUserNotificationSettings for two different notificationSettings - one without a notificationCategory and one with a notificationCategory:
//Request notification permission
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
//Request notification permission again, but with a category with no actions
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
category.identifier = @"com.xyz.markNotificationPopupShownCategoryIdentifier";
UIUserNotificationSettings *notificationSettingsWithCategory = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:[NSSet setWithObject:category]];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettingsWithCategory];
The didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings method in the app delegate will be called two times, and irrespective of the user's answer in the permission notification, after the second call, the current notification settings will contain the category. As long as the category count is greater than 0, you can know for sure that the notifications permission dialog has been shown:
if ([UIApplication sharedApplication].currentUserNotificationSettings.categories.count > 0) {
NSLog(@"Notifications permission has been asked");
} else {
NSLog(@"Notifications permission hasn't been asked");
}