Я хочу реализовать настраиваемый экран, который информирует моих пользователей, почему я собираюсь запрашивать разрешения на push-уведомления. После того, как они нажимают кнопку на этом настраиваемом экране, я представляю диалоговое окно разрешения push-уведомлений iOS с [[UIApplication sharedApplication] registerForRemoteNotificationTypes:

Я хочу отображать этот настраиваемый экран только один раз , если пользователь еще не видел диалоговое окно разрешения push-уведомлений. Я не могу использовать [[UIApplication sharedApplication] enabledRemoteNotificationTypes] == UIRemoteNotificationTypeNone, так как это также вернет "none", если пользователь решил не разрешать push-уведомления.

Любые идеи кто-нибудь?

25
Jovan 12 Авг 2014 в 16:22

3 ответа

Лучший ответ

Вы можете использовать NSUserDefaults:

#define kPushNotificationRequestAlreadySeen @"PushNotificationRequestAlreadySeen"

if(![[NSUserDefaults standardUserDefaults] boolForKey:kPushNotificationRequestAlreadySeen]) {

    // Notify the user why you want to have push notifications
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:... delegate:self ...];
    [alertView show];

    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kPushNotificationRequestAlreadySeen];
}
else {
    // Already allowed -> register without notifying the user
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}

А также

- (void)alertView:(UIAlertView*)alertView didDismissWithButtonIndex:(NSInteger)index {
    // Actually registering to push notifications
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}
6
matt.P 12 Авг 2014 в 12:47

Решение, которое я нашел, похоже на взлом, но оно работает. Вам нужно вызвать registerUserNotificationSettings для двух разных настроек notificationSettings - одного без notificationCategory и другого с 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];

Метод didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings в делегате приложения будет вызываться два раза, и независимо от ответа пользователя в уведомлении о разрешении после второго вызова текущие настройки уведомления будут содержать категорию. Пока количество категорий больше 0, вы можете точно знать, что был показан диалог разрешения уведомлений:

if ([UIApplication sharedApplication].currentUserNotificationSettings.categories.count > 0) {
    NSLog(@"Notifications permission has been asked");
} else {
    NSLog(@"Notifications permission hasn't been asked");
}
-1
Peter Robert 6 Мар 2015 в 09:26

Это просто обходной путь, но он будет работать в большинстве случаев.

Когда iOS предлагает пользователю разрешить push-уведомления, вызывается applicationWillResignActive.

После вызова registerForRemoteNotificationTypes ... запустите таймер (или dispatch_after), который покажет пользователю новое предупреждение, объясняющее, что им нужно будет использовать приложение настроек для включения уведомлений. Затем в applicationWillResignActive отмените таймер. Таким образом, предупреждение с объяснением будет отображаться только в том случае, если applicationWillResignActive никогда не вызывается.

Единственная проблема, которую я вижу в этом, заключается в том, что приложение выходит из строя по другим причинам именно в то время, когда срабатывает таймер ... но это не ставит вас в худшую ситуацию, в которой вы уже находитесь, и имеет преимущество работы в в большинстве случаев.

1
Luke Rhodes 16 Дек 2014 в 01:30