Можно ли узнать, было ли приложение запущено / открыто из push-уведомления?
Я предполагаю, что событие запуска может быть поймано здесь:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
// Launched from push notification
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
}
Тем не менее, как я могу обнаружить, что он был открыт из push-уведомления, когда приложение было в фоновом режиме?
Ответы:
Смотрите этот код:
такой же как
источник
поздно, но может быть полезно
Когда приложение не запущено
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
называется ..
где нужно проверить push-уведомление
источник
У нас была проблема с корректным обновлением представления после запуска приложения. Здесь есть сложные последовательности методов жизненного цикла, которые сбивают с толку.
Методы жизненного цикла
Наше тестирование для iOS 10 выявило следующие последовательности методов жизненного цикла для различных случаев:
Эта проблема
Хорошо, теперь нам нужно:
Сложность в том, что обновление представления должно происходить, когда приложение фактически становится активным, что является одним и тем же методом жизненного цикла во всех случаях.
Эскиз нашего решения
Вот основные компоненты нашего решения:
notificationUserInfo
переменную экземпляра в AppDelegate.notificationUserInfo = nil
в обаapplicationWillEnterForeground
иdidFinishLaunchingWithOptions
.notificationUserInfo = userInfo
вdidReceiveRemoteNotification:inactive
applicationDidBecomeActive
всегда вызывайте пользовательский методopenViewFromNotification
и передавайтеself.notificationUserInfo
. Еслиself.notificationUserInfo
nil, тогда вернитесь раньше, иначе откройте представление на основе состояния уведомления, найденного вself.notificationUserInfo
.объяснение
При открытии из push
didFinishLaunchingWithOptions
илиapplicationWillEnterForeground
всегда вызывается непосредственно перед этимdidReceiveRemoteNotification:inactive
, поэтому мы сначала сбрасываем NotionUserInfo в этих методах, чтобы не было устаревшего состояния. Затем, еслиdidReceiveRemoteNotification:inactive
вызывается, мы знаем, что мы открываем с толчка, поэтому мы устанавливаем,self.notificationUserInfo
который затем выбирается,applicationDidBecomeActive
чтобы направить пользователя к правильному представлению.Существует один последний случай, когда пользователь открывает приложение в переключателе приложений (т. Е. Дважды нажав кнопку «Домой», когда приложение находится на переднем плане), а затем получает push-уведомление. В этом случае
didReceiveRemoteNotification:inactive
вызывается только и не вызывается ни WillEnterForeground, ни didFinishLaunching, так что вам нужно какое-то специальное состояние для обработки этого случая.Надеюсь это поможет.
источник
receive
методах, когда состояние приложения активно или приложение возобновляет работу. Это может привести к проблемам со сменой VC, когда приложение все еще неактивно. Ваше решение выглядит великолепно, пока Apple снова не изменит жизненный цикл.applicationWillResignActive
называетсяapplicationDidBecomeActive
. Поэтому послеapplicationWillResignActive
вызова не сохраняйте полученное уведомление до вызоваapplicationDidEnterBackground
илиapplicationDidBecomeActive
.Это хорошо изношенный пост ... но в нем все еще отсутствует реальное решение проблемы (как указано в различных комментариях).
Причину можно увидеть в потоке вызовов, когда приходит уведомление,
application:didReceiveRemoteNotification...
вызывается при получении уведомления И снова, когда уведомление прослушивается пользователем. Из-за этого вы не можете сказать, просто взглянув на
UIApplicationState
то, нажал ли пользователь.Кроме того, вам больше не нужно справляться с ситуацией «холодного старта» приложения в том
application:didFinishLaunchingWithOptions...
виде, в каком онapplication:didReceiveRemoteNotification...
вызывается снова после запуска в iOS 9+ (возможно, и в 8).Итак, как вы можете определить, что пользователь нажал на цепочку событий? Мое решение состоит в том, чтобы отметить время, когда приложение начинает выходить из фона или холодного запуска, а затем отметить это время
application:didReceiveRemoteNotification...
. Если оно меньше 0,1 с, то вы можете быть уверены, что нажатие вызвало запуск.Swift 2.x
Swift 3
Я проверил это для обоих случаев (приложение в фоновом режиме, приложение не запущено) на iOS 9+, и оно работает как шарм. 0,1 с тоже довольно консервативно, фактическое значение ~ 0,002 с, поэтому 0,01 тоже хорошо.
источник
UNNotificationCenter
API, в частности методы UNNotificationCenterDelegate. Эти API вызываютuserNotificationCenter(UNUserNotificationCenter, didReceive: UNNotificationResponse, withCompletionHandler: @escaping () -> Void)
метод func только тогда, когда пользователь фактически нажал на уведомление.applicationWillEnterForeground
вызов, в результате решение не может обнаружить касание.UNUserNotificationCenter.current().delegate
вapplication:didFinishLaunchingWithOptions
, приложение будет звонитьuserNotificationCenter(didReceive response)
после нажатия в случае, который вы описалиКогда приложение закрывается, и пользователь нажимает на push-уведомление
Когда приложение находится в фоновом режиме, и пользователь нажимает на push-уведомления
В зависимости от вашего приложения, оно также может отправлять вам тихий толчок
content-available
внутриaps
, так что имейте это в виду :) См. Https://stackoverflow.com/a/33778990/1418457источник
Swift 2.0 для состояния «не работает» (локальное и удаленное уведомление)
источник
В
application:didReceiveRemoteNotification:
проверке того , как вы получили уведомление , когда приложение находится на переднем плане или в виде фона.Если оно было получено в фоновом режиме, запустите приложение из уведомления.
источник
Для быстрой:
источник
Да, вы можете определить этот метод в appDelegate :
Для местного уведомления:
источник
если кто-то хочет получить ответ в Свифт 3
источник
Размещать это для пользователей Xamarin.
Ключом к определению того, было ли приложение запущено с помощью push-уведомления, является
AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options)
метод и словарь опций, которые передаются.Словарь вариантов будет иметь этот ключ в нем , если это локальное оповещение:
UIApplication.LaunchOptionsLocalNotificationKey
.Если это удаленное уведомление, оно будет
UIApplication.LaunchOptionsRemoteNotificationKey
.Когда ключ
LaunchOptionsLocalNotificationKey
, объект имеет типUILocalNotification
. Затем вы можете посмотреть на уведомление и определить, какое именно это уведомление.Pro-tip: в нем
UILocalNotification
нет идентификатора, как и в случае с идентификаторомUNNotificationRequest
. Поместите ключ словаря в UserInfo, содержащий requestId, чтобы при тестировании уUILocalNotification
вас был конкретный requestId, на котором можно основывать некоторую логику.Я обнаружил, что даже на устройствах с iOS 10+, когда при создании уведомлений о местоположении с помощью
UNUserNotificationCenter
«AddNotificationRequest
&»UNMutableNotificationContent
, когда приложение не запущено (я его убил) и запускается нажатием на уведомление в центре уведомлений, словарь по-прежнему содержитUILocalNotificaiton
объект.Это означает, что мой код, который проверяет запуск на основе уведомлений, будет работать на устройствах iOS8 и iOS 10+
источник
Прямо из документации по
Если приложение работает и получает удаленное уведомление, приложение вызывает этот метод для обработки уведомления.
Ваша реализация этого метода должна использовать уведомление, чтобы принять надлежащий курс действий.
И чуть позже
Если приложение не запускается при получении push-уведомления, метод запускает приложение и предоставляет соответствующую информацию в словаре параметров запуска.
Приложение не вызывает этот метод для обработки этого push-уведомления.
Вместо этого ваша реализация
или
Метод должен получить данные полезных данных push-уведомлений и ответить соответствующим образом.
источник
Я начну с диаграммы состояний, которую я создал для своего собственного использования, чтобы более точно ее визуализировать и рассмотреть все другие состояния: https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UKpBwASlT6ZkUIFTHLGWLGWGW1W1W7 ? GID = 0 & = одна истинная
Используя эту таблицу, мы можем увидеть, что на самом деле требуется для разработки надежной системы обработки уведомлений, которая работает практически во всех возможных случаях использования.
Комплексное решение ↓
Примечание. Аналогичный ответ предлагается в комментариях к ответу Эрика, однако лист состояния помогает найти все возможные сценарии, как я делал в своем приложении.
Пожалуйста, найдите полный код ниже и комментарий ниже, если какой-либо конкретный случай не обрабатывается:
AppDelegate
NotificationUtils : здесь вы можете написать весь свой код для навигации по различным частям приложения, обработки баз данных (CoreData / Realm) и выполнения всех других действий, которые необходимо выполнить при получении уведомления.
источник
источник
Существует только один надежный способ, и он работает только для iOS 10+ :
Используя метод
UNUserNotificationCenter
реализацииUNUserNotificationCenterDelegate
:источник
Ты можешь использовать:
обрабатывать удаленные push-уведомления.
Проверьте здесь документацию
источник
Я еще не пробовал, но, может быть, вы могли бы отправить себе уведомление? http://nshipster.com/nsnotification-and-nsnotificationcenter/
источник
источник
Проблема с этим вопросом заключается в том, что «открытие» приложения не является четко определенным. Приложение либо запускается в холодном режиме из неработающего состояния, либо повторно активируется из неактивного состояния (например, из-за переключения обратно в другое приложение). Вот мое решение, чтобы различать все эти возможные состояния:
И
MXDefaults
это просто небольшая обертка дляNSUserDefaults
.источник
Для
swift
источник
Xcode 10 Swift 4.2
источник
Для iOS 10+ вы можете использовать этот метод, чтобы узнать, когда нажимается ваше уведомление, независимо от состояния приложения.
источник
Ответ М.Отмана верен для приложений, которые не содержат делегата сцены. Для приложений делегирования сцены. Это сработало для меня на iOS 13.
Вот код, который должен быть написан в сцене подключения
Код для делегата приложения для поддержки более ранних версий didFinishLaunchingWithOptions
источник
Для пользователей Swift:
Если вы хотите открыть другую страницу при открытии из push или что-то в этом роде, вам нужно проверить это
didFinishLaunchingWithOptions
следующим образом:источник
В SWIFT:
Я запускаю Push-уведомления (с фоновой загрузкой). Когда мое приложение работает в фоновом режиме и я получаю push-уведомление, я обнаружил, что didReceiveRemoteNotification в appDelegate будет вызываться дважды; один раз, когда уведомление получено, и другой, когда пользователь нажимает на уведомление уведомления.
Чтобы определить, была ли нажата кнопка уведомления об уведомлении, просто проверьте, является ли необработанное значение applicationState == 1 внутри didReceiveRemoteNotification в appDelegate.
Надеюсь, это поможет.
источник
Когда приложение в фоновом режиме, как Shanegao вы можете использовать
Но если вы хотите запустить приложение и когда приложение закрыто, и вы хотите отладить свое приложение, вы можете перейти к Edit Scheme и в левом меню выбрать Run, а затем в запуске выбрать Wait for exetable для запуска, а затем вы запускаете приложение, когда вы нажмите на push-уведомление
Редактировать схему> Выполнить> Дождаться запуска исполняемого файла
источник