UILocalNotification не срабатывает на устройстве ios9 (баннер не отображается)

Это уведомление отлично срабатывает в Simulator (9.2) и не срабатывает на iPhone 6 (9.2):

UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = NSLocalizedString(@"You are going to be disconnected. To continue being online, please open the application",nil);
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];

и я вызываю этот код из:

- (void)applicationDidEnterBackground:(UIApplication *)application {
[self performSelector:@selector(sendLocalNotification) withObject:nil afterDelay:5];
}

Удаленные уведомления работают нормально для всех клиентов


person protspace    schedule 15.12.2015    source источник


Ответы (4)


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

person Alex Wulff    schedule 15.12.2015
comment
ручная переустановка не помогла. Пробовал два устройства с ios9.2 - локальный баннер уведомлений не появляется (хотя сегодня я вижу уведомление в верхней шторке) - person protspace; 16.12.2015

Проблема в том, что вы пытаетесь что-то вызвать после того, как приложение вошло в фоновый режим. Это неправильно и работать не будет, статей о запуске фоновых задач на iOS много.

Вы можете запланировать уведомление следующим образом:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    UILocalNotification* localNotification = [[UILocalNotification alloc] init];
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    localNotification.alertBody = NSLocalizedString(@"You are going to be disconnected.", nil);
    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5.0];
    [application scheduleLocalNotification:localNotification];
}

Если пользователь открывает ваше приложение до истечения этого 5-секундного интервала, вы можете отменить это уведомление:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [application cancelLocalNotification:application];
    // If you don't want to keep reference to the notification
    // [application cancelAllLocalNotifications];
}
person kelin    schedule 16.12.2015
comment
Я делаю именно так, как вы описали. Планирование в applicationDidEnterBackground и отмена в applicationDidBecomeActive. В симуляторе работает нормально, в устройстве нет (уведомления появляются в верхней шторке, но не отображаются в виде баннера на трамплине) - person protspace; 16.12.2015
comment
@protspace, попробуйте перезагрузить устройство. - person kelin; 16.12.2015
comment
перезагружал несколько раз - не помогло. Также я заметил, что вижу баннеры сразу после открытия приложения (снова отправьте его на передний план). Похоже, они просто ждут, когда я открою приложение. Но они не отображаются, пока приложение находится в фоновом режиме ( - person protspace; 16.12.2015
comment
Что ж, тогда вы можете попробовать сообщить об этом в Apple. - person kelin; 16.12.2015

Если вы хотите запустить локальное уведомление, например: через 5 секунд используйте этот код:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    UILocalNotification* localNotification = [UILocalNotification new];
    localNotification.fireDate = [[NSDate new] dateByAddingTimeInterval:5]; // Notification will be fired after 5 since now.
    localNotification.alertBody = @"Your alert message";
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}

ВНИМАНИЕ: Если вы хотите получать уведомления, вы должны запросить у пользователя разрешение, например:

UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];

[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];

Код разрешения, указанный выше, может быть вызван в вашем методе AppDelegate.m, например: в методе didFinishLaunchingWithOptions. Вы должны знать, что метод performSelector не подходит в этом случае, каждый UILocalNotification имеет свойство fireDate, которое должно использоваться для запуска уведомления с заданной задержкой NSDate.


ОБНОВИТЬ

Сегодня у меня была такая же проблема, я передал пустую строку alertBody, и уведомление не появилось. Так что на мой взгляд ваш

NSLocalizedString(@"You are going to be disconnected. To continue being online, please open the application",nil);

возвращает пустую строку или ноль.

Попробуйте присвоить свойству alertBody любую другую строку, например.

localNotification.alertBody = @"test" 

должно работать :)

Часть документа Apple:

Декларация SWIFT

вар alertBody: Строка?

Обсуждение Назначьте строку или, что предпочтительнее, ключ локализованной строки (используя NSLocalizedString) в качестве значения сообщения. Если значение этого свойства не равно нулю, отображается предупреждение. Значение по умолчанию — nil (нет предупреждения). Экранирующие символы в стиле Printf удаляются из строки перед отображением; чтобы включить в сообщение символ процента (%), используйте два символа процента (%%).

person Robert    schedule 15.12.2015
comment
Ваш код тоже не работает. И разрешение спросил именно так, как вы описали. Также я хочу сказать, что удаление push-уведомлений работает нормально для всех клиентов. Только локальные уведомления не приходят на устройство (а приходят на симулятор). - person protspace; 16.12.2015
comment
Вы уверены, что включили уведомления для своего приложения в настройках? - person Robert; 16.12.2015
comment
уведомления включены. Также я заметил, что уведомления на самом деле появляются в верхней шторке в сегменте уведомлений. Но они не отображаются на экране во время спринтборда. - person protspace; 16.12.2015
comment
благодарю вас. Но я обнаружил проблему: проблема заключалась в том, что я использовал PerformSelector, но должен использовать PerformSelectorInBackground. PerformSelector не работает, если приложение находится в фоновом режиме. - person protspace; 17.12.2015
comment
но для этой цели вы должны использовать fireDate, но ладно :) - person Robert; 17.12.2015

проблема заключалась в том, что я использовал PerformSelector, но должен использовать PerformSelectorInBackground

PerformSelector не работает, если приложение находится в фоновом режиме

person protspace    schedule 16.12.2015