Тихие push-уведомления доставляются только в том случае, если устройство заряжается и / или приложение находится на переднем плане
Я реализовал тихие push-уведомления, но заметил странное поведение. Беззвучные push-уведомления обрабатываются с помощью:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
Тихие push-сообщения, похоже, принимаются только в том случае, если устройство заряжается (т. Е. Подключен кабель) и / или если мое приложение находится на переднем плане.
Если я отключаю устройство от зарядного устройства (или Mac), то тихие push-уведомления больше не принимаются, если приложение не на переднем плане.
Обычно я получаю не тихие push-уведомления в обоих случаях.
Если я снова подключу USB-кабель, то получу ожидаемое поведение и получу беззвучные push-уведомления независимо от того, находится ли приложение на переднем или на заднем плане.
Я использую UILocalNotification, поэтому я знаю, что получено.
Тот факт, что все это работает нормально с подключенным устройством, говорит о том, что мои уведомления с молчаливыми нажатиями настроены правильно, и в приложении установлены правильные режимы фона, заданные в plist и т. Д.
Такое поведение повторяется на iPhone 5s, 6 и iPad 2, работающих под управлением IOS 8 или 8.1.
Кто-нибудь еще испытывал это? Это должно быть легко воспроизвести. Почему простое действие по подключению устройства к зарядному устройству должно изменить возможность получения тихих push-уведомлений?
8 ответов
Мы испытали такое же поведение и пытались понять, почему iOS решает доставлять одни уведомления, а другие нет.
То, что мы разработали до сих пор:
Сообщения будут получать более надежно в фоновом режиме, когда на Wi-Fi, чем на сотовые данные. Фактически, когда в сотовой сети (3g/4g), если уровень вашего сигнала недостаточно силен, iOS получает push-сообщение, но не разбудит ваше приложение. Мы разместили на форумах Apple об этом здесь: https://devforums.apple.com/message/1069814. Мы также открыли тикет поддержки, и команда поддержки попросила нас подать его в виде отчета об ошибке, что мы сделали пару недель назад и все еще ждем ответа.
Когда вы получаете push-сообщение, вам нужно как можно скорее вызвать fetchCompletionHandler. Технически у вас есть 30 секунд для выполнения фоновой обработки, но в iOS есть формула, согласно которой, чем чаще вы отправляете push-сообщения и в зависимости от того, сколько времени вы тратите на обработку этих сообщений, прежде чем вернуть приложение в приостановленное состояние, iOS может уменьшить объем раз ваше приложение просыпается в будущем.
Смотрите здесь, от Apple didReceiveRemoteNotification: fetchCompletionHandler: документация:
Как только вы закончите обработку уведомления, вы должны вызвать блок в параметре обработчика, иначе ваше приложение будет закрыто. Ваше приложение имеет до 30 секунд времени настенных часов для обработки уведомления и вызова указанного блока обработчика завершения. На практике вам следует вызывать блок обработчика, как только вы закончите обработку уведомления. Система отслеживает затраченное время, энергопотребление и стоимость данных для фоновых загрузок вашего приложения. Приложения, которые используют значительную мощность при обработке push-уведомлений, не всегда могут быть разбужены рано для обработки будущих уведомлений.
В нашем тестировании мы отправляли частые тихие push-уведомления в наше приложение (каждые 10 - 30 секунд). И приложение не спит около 3 секунд, прежде чем мы вернем его обратно в режим сна. Со временем мы определенно заметили снижение частоты, с которой наше приложение просыпается до такой степени, что iOS будет запускать приложение только каждые 15 - 30 минут. Так что, похоже, существует какая-то формула затухания / регулирования, но мы не можем найти никакой документации о том, как именно она работает. Мы запросили эту формулу и переменные у Apple в качестве запроса на поддержку, но они ответили: "Запрашиваемая вами информация не является общедоступной" и снова попросили нас подать отчет об ошибке.
Итак, надеюсь, это полезно? Мы все еще пытаемся узнать больше сами, поэтому я нашел этот вопрос:)
С iOS8 фоновая доставка в приложения изменилась. Фоновый толчок теперь будет доставляться в приложение только при определенных обстоятельствах. Apple не указала в явном виде, в чем именно состоят эти обстоятельства, но, исходя из моих обширных экспериментов, все сводится к тому, заряжается телефон или нет. Есть некоторые другие переменные в игре (такие как тип сети, тип устройства, включенный Wi-Fi), но основной основной фактор - это заряжается устройство или нет, когда приходит пуш.
Если телефон заряжается от прямого сетевого источника питания или косвенно через USB-соединение с компьютером, то подавляющее большинство времени будет доставляться в приложение. Но отсоедините телефон от источника питания или USB, и фоновое нажатие почти никогда не будет доставлено в приложение, даже если батарея телефона заряжена на 100%.
Вы можете очень легко это проверить, просто отправив несколько нажатий, когда телефон заряжается, а когда нет. НО вы должны принять во внимание, что фоновые изменения в сборке разработки и использовании среды "песочницы" НЕ ведут себя так же, как фоновые изменения в производственной сборке и производственной среде, фоновые изменения на самом деле более вероятны для доставки в приложение в процессе разработки. затем они находятся в производстве, поэтому крайне важно, чтобы вы тестировали, используя производственную сборку и производственную среду Apple, чтобы увидеть реальные результаты.
Обратите внимание, что есть два шага принудительной доставки, во-первых, он должен быть доставлен на сам телефон, во-вторых, как только телефон получит его, он должен быть доставлен операционной системой в приложение. В iOS7 такие вещи, как тьюринг по Wi-Fi, увеличивали шансы того, что пуш доберется до телефона. Однако с iOS8, даже несмотря на то, что push-сообщение успешно доставляется на телефон, ОС не передает его в фоновое приложение, если телефон не заряжается. Это означает, что телефон получает уведомление и удерживает его, иногда в течение нескольких часов, прежде чем он сможет переслать его в приложение, если телефон не заряжается.
Я столкнулся с той же проблемой, и причина, по которой я не получаю push-уведомления, когда приложение не заряжается, заключается в том, что когда режим низкого энергопотребления включен из Settings > Battery
это отключает background-fetch
функция для всех приложений.
Что мешает устройству получать push-уведомления.
Эта ссылка может быть полезной. Документация Apple
Я также заметил то же самое и потратил некоторое время на выяснение. См. /questions/20038722/vozmozhnyi-li-silent-remote-notifications-esli-polzovatel-otklyuchil-funktsiyu-push-uvedomlenij-dlya-prilozheniya/20038731#20038731
Если вы выключили Bg App Refresh, тихий удаленный пуш будет тихо отброшен (ирония).
Тем не менее, я заметил, что если вы подключаетесь к XCode через кабель, каким-то образом настройка Bg App Refresh игнорируется, и все тихие нажатия для вашего приложения работают.
Я очень подозреваю, что это недокументированная функция: зарядка игнорирует настройку Bg App Refresh.
Это не работает, потому что вы включили неправильный фоновый режим в списке. Вам необходимо включить remote-notification
тег (приложение загружает контент в ответ на push-уведомления), а не извлекает. Выборка используется для чего-то другого. Вам также может понадобиться использовать ключ доступного содержимого в полезной нагрузке JSON, например:
{
"aps": {
"content-available": 1
},
"yourdatakey":{data}
}
Я надеюсь, что вы используете APNS, предоставляя приоритет "CONSERVE_POWER" (5)
попробуйте изменить это как "IMMEDIATE" (10)
Я уже давно сталкиваюсь с этой проблемой, и я очень благодарен за этот вопрос и @Kevin D., которые делятся своим пониманием. Я начинаю думать, что /questions/3735253/push-uvedomleniya-kotoryie-zapuskayut-fonovoe-obnovlenie-pered-otobrazheniem-push-uvedomlenij-vs-tihij-push/3735268#3735268 и https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html (см. priority
в одной из таблиц) описывают, почему мое приложение имеет проблемы:
Ошибочно использовать этот приоритет для толчка, который содержит только
content-available
ключ.
Для отправки уведомлений я использую node-apn, где по умолчанию (который мне тоже нужен) является установка приоритета max (10
[Остерегайтесь, похоже, только 10
а также 5
правильные значения в это время]), но так как я хотел тихое уведомление, у меня нет alert
, badge
, или же sound
задавать.
Я нашел другое решение, которое работает для меня, используя PushKit Framework
Push-сигналы VoIP предоставляют дополнительные функциональные возможности в дополнение к стандартному push-запросу, который необходим приложениям VoIP для выполнения обработки push-уведомлений перед отображением уведомления для пользователя.
Когда я отправляю VOIP Push, приложение просыпается независимо от состояния приложения и может выполнять любые операции.
Зарегистрируйтесь для получения VOIP PushNotification в didFinishLaunchingWithOptions
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
if([credentials.token length] == 0) {
NSLog(@"voip token NULL");
return;
}
NSString *originalToken=[NSString stringWithFormat:@"%@",credentials.token];
NSString *token = [originalToken stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"PushCredentials: %@",token);}
тогда вы можете обработать любую фоновую выборку в этой функции, как только вы получите VOIP PushNotification
-(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
ПРИМЕЧАНИЕ: вы должны использовать сертификат, который включает сертификат услуг VoIP