iOS push notification: как определить, если пользователь нажал на уведомление, когда приложение находится в фоновом режиме?


есть много потоков stackoverflow по этой теме, но я все еще не нашел хорошего решения.

если приложение не в фоновом режиме, я могу проверить launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] на application:didFinishLaunchingWithOptions: вызов, чтобы увидеть, если он открыт из уведомления.

если приложение находится в фоновом режиме, все сообщения предлагают использовать application:didReceiveRemoteNotification: и проверьте состояние приложения. Но как я экспериментировал (а также как следует из названия этого API), этот метод вызывается при получении уведомления, вместо того, чтобы постучать.

Итак, проблема в том, что если приложение запускается, а затем заземляется, и вы знаете, что уведомление получено от application:didReceiveNotification (application:didFinishLaunchWithOptions: не срабатывает в этот момент), как вы знаете, если пользователь продолжит приложение, нажав на уведомление, или просто нажав на значок приложения? Потому что если пользователь нажал уведомление, ожидание состоит в том, чтобы открыть страницу, указанную в этом уведомлении. В противном случае он не должен.

я мог бы использовать handleActionWithIdentifier для пользовательских действий уведомления, но это срабатывает только при нажатии кнопки пользовательского действия, а не когда пользователь нажимает на основной текст уведомления.

спасибо.

EDIT:

прочитав один ответ ниже, я подумал, что таким образом я могу прояснить свой вопрос:

как мы можем различать эти 2 сценария:

(A) 1.приложение переходит в фоновый режим; 2.уведомления; 3. пользователь нажимает на уведомление; 4. приложение входит передний план

(B) 1.приложение переходит в фоновый режим; 2.уведомления; 3. пользователь игнорирует уведомления и нажимает на значок приложения; 4. приложение выходит на передний план

С application:didReceiveRemoteNotification: срабатывает в обоих случаях на Шаге 2.

или application:didReceiveRemoteNotification: запускаться на Шаге 3 только для (A), но я как-то неправильно настроил свое приложение, поэтому я вижу его на Шаге 2?

8 83

8 ответов:

хорошо, я наконец понял.

на вкладке целевые настройки Capabilities возможности ➝ фоновые режимы, если вы установите флажок "удаленные уведомления",application:didReceiveRemoteNotification: будет срабатывать, как только уведомление приходит (пока приложение находится в фоновом режиме), и в этом случае нет никакого способа, чтобы сказать, будет ли пользователь нажать на уведомление.

Если вы снимите этот флажок,application:didReceiveRemoteNotification: будет срабатывать только при нажатии на уведомление.

Это немного странно, что установка этого флажка изменит поведение одного из методов делегата приложения. Было бы лучше, если бы этот флажок был установлен, Apple использует два разных метода делегирования для получения уведомлений и уведомления tap. Я думаю, что большинство разработчиков всегда хотят знать, если уведомление прослушивается или нет.

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

enter image description here

Я ищу то же самое, что вы и на самом деле нашел решение, которое не требует удаленного уведомления отчитали.

чтобы проверить, нажал ли пользователь, или приложение находится в фоновом режиме или активно, вам просто нужно проверить состояние приложения в

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    if(application.applicationState == UIApplicationStateActive) {

        //app is currently active, can update badges count here

    }else if(application.applicationState == UIApplicationStateBackground){

        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here

    }else if(application.applicationState == UIApplicationStateInactive){

        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here

    }

для получения дополнительной информации проверьте:

Основы Программирования С Использованием UIKit Ссылка > UIApplication Класс Ссылка > UIApplicationState

по данным iOS / XCode: как узнать, что приложение было запущено с помощью щелчка по уведомлению или значку приложения springboard? вы должны проверить состояние приложения в didReceiveLocalNotification следующим образом:

if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
{
    // user has tapped notification
}
else
{
    // user opened app from app icon
}

хотя это не имеет для меня полного смысла, это, кажется, работает.

Если кто-то хочет его в Swift 3.0

switch application.applicationState {
    case .active:
        //app is currently active, can update badges count here
        break
    case .inactive:
        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
        break
    case .background:
        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
        break
    default:
        break
    }

если у вас есть" фоновые режимы " > "удаленные уведомления" проверено = = да, нажмите на событие уведомления прибудет в:

-(void)userNotificationCenter:(UNUserNotificationCenter *)center **didReceiveNotificationResponse**:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler.

это помогло мне. Пожалуйста, наслаждайтесь :)

я столкнулся с этой проблемой, но на iOS 11 С Новым UserNotifications основы.

вот для меня это так:

  • Новый Запуск: application:didFinishLaunchingWithOptions:
  • получено на переднем плане:application:didReceiveRemoteNotification:fetchCompletionHandler:
  • получено в фоновом режиме:userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:

в моем случае, фоновый режим выключен не имеет никакого значения. Однако, когда приложение было приостановлено, и пользователь нажал уведомление, я мог бы справиться с этим случаем в этом методе обратного вызова:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {

}

вы можете настроить полезную нагрузку вашего push-уведомления для вызова делегата приложения application:didReceiveRemoteNotification:fetchCompletionHandler: метод, когда приложение находится в фоновом режиме. Вы можете установить здесь какой-то флаг, чтобы при следующем запуске приложения пользователь мог выполнить свою операцию.

из документации apple вы должны использовать эти методы для загрузки нового контента, связанного с push-уведомлением. Кроме того, чтобы это работало, вы должны включить удаленное уведомление из фоновых режимов и полезной нагрузки push-уведомления должен содержать content-available ключ со значением 1. Дополнительную информацию см. В разделе использование Push-уведомлений для запуска раздела Загрузки из apple doc здесь.

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

надеюсь, что это поможет вам.