Обнаруживать, если приложение: didReceiveRemoteNotification: fetchCompletionHandler: вызывается путем нажатия на уведомление в Notification Center
application: didReceiveRemoteNotification: fetchCompletionHandler:
отличается от
application: didReceiveRemoteNotification:
Как? из документов:
В отличие от приложения: didReceiveRemoteNotification: метод, который вызывается только тогда, когда ваше приложение запущено, система вызывает этот метод независимо от состояния вашего приложения. Если ваше приложение приостановлено или нет работает, система просыпается или запускает ваше приложение и помещает его в перед запуском метода. Если пользователь открывает ваше приложение из системного предупреждения, система вызывает этот метод снова, чтобы вы знали, какое уведомление пользователь выбрал.
Моя борьба такова: я хочу знать, вызвал ли этот метод пользователь, нажав на системное предупреждение из Центра уведомлений или из молчащего push-уведомления, которое просыпает устройство. В настоящее время, насколько я вижу, нет очевидного способа дифференцировать.
- (BOOL)application: didFinishLaunchingWithOptions:
Отслеживание launchOptions в вышеуказанном методе не является решением, потому что оно вызывается только в том случае, если приложение приостановлено/не работает в фоновом режиме. Если он работает в фоновом режиме, он не вызван.
Ответы
Ответ 1
Документы Apple немного запутывают
application: didReceiveRemoteNotification: fetchCompletionHandler:
используется, если ваше приложение поддерживает фоновый режим удаленного уведомления (т.е. вы делаете BackgroundFetch.)
application: didReceiveRemoteNotification:
вызывается, когда ОС получает RemoteNotification и приложение работает (в фоновом режиме/приостановлено или на переднем плане.)
Вы можете проверить UIApplicationState, чтобы увидеть, было ли приложение перенесено на передний план пользователем (нажатие на уведомление) или уже было запущено при получении уведомления.
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIApplicationState state = [application applicationState];
// user tapped notification while app was in background
if (state == UIApplicationStateInactive || state == UIApplicationStateBackground) {
// go to screen relevant to Notification content
} else {
// App is in UIApplicationStateActive (running in foreground)
// perhaps show an UIAlertView
}
}
Ответ 2
Вы можете проверить UIApplication
applicationState
, чтобы отличать бесшумные вызовы от вызовов, сделанных при активном использовании пользователем:
typedef enum : NSInteger {
UIApplicationStateActive,
UIApplicationStateInactive,
UIApplicationStateBackground
} UIApplicationState;
Или сохраните свой собственный флаг на delegate
applicationDidEnterBackground:
.
Ответ 3
Состояние приложения не является надежным, потому что, если у вас есть центр управления или центр уведомлений Apple, открывающий ваше приложение, приложение: didReceiveRemoteNotification: fetchCompletionHandler: вызывается и состояние приложения будет неактивным.
У меня такая же проблема, когда я пытаюсь ответить на клик на уведомлении, когда приложение находится в фоновом режиме, и, похоже, нет надежного способа однозначно идентифицировать это.
Ответ 4
Когда метод application: didReceiveRemoteNotification:fetchCompletionHandler:
называется состоянием приложения UIApplicationStateInactive
, если пользователь нажимает на предупреждение (в этом случае вы хотите подготовить некоторый пользовательский интерфейс) и UIApplicationStateBackground
, когда приложение тихо просыпается (в этом случае вы просто загружаете некоторые данные).
Ответ 5
Я не уверен, понимаю ли я ваш вопрос.
Вы хотите различать тональный сигнал фоновой подсветки push push и шумное push-уведомление? Вы можете просто проверить, содержит ли словарь push-сообщения "доступный контент": [[userInfo objectForKey:@"aps"] objectForKey:@"content-available"]
Если это так, то это должно быть тихим нажатием. Если нет, это был обычный толчок.
Вы хотите узнать, вызывается ли этот метод фоновой выборки, когда приложение получает уведомление и оно приостановлено/не работает? Если это так, вы можете сделать следующее:
- Загрузите и импортируйте LumberJacks в свое приложение. Просмотрите направления и узнайте, как настроить его таким образом, чтобы вы могли сохранять журналы на диск.
-
Поместите это в любой метод, который вы хотите увидеть, будет ли/когда этот метод вызывается:
-
DDLogDebug(@"%@ - %@",NSStringFromSelector(_cmd),NSStringFromClass([self class]));
Это напечатает класс и метод в файле журнала.
-
Изучите файл журнала после отправки push-уведомления вашему включенному приложению фоновой выборки и посмотрите, вызван ли какой-либо из методов, просматривая ваш файл журнала.
Если вы правильно настроили приложение для фоновой выборки, метод application: didReceiveRemoteNotification: fetchCompletionHandler:
будет вызван даже тогда, когда приложение будет заложено/не запущено, если вы получите push-уведомление (тихий push или нет).
Ответ 6
В случае быстрого
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let state : UIApplicationState = application.applicationState
if (state == .Inactive || state == .Background) {
// go to screen relevant to Notification content
} else {
// App is in UIApplicationStateActive (running in foreground)
}
}
Ответ 7
Для Swift: в application(_:didFinishLaunchingWithOptions:)
проанализируйте параметры приложения. Если они существуют, вы знаете, что приложение было запущено из них.
if let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any] {
print("Remote notfi is \(remoteNotif)")
if let notification = remoteNotif["aps"] as? [AnyHashable : Any] {
/// - parse notification
}
}
В противном случае вы можете обращаться с краном, и знаете, что приложение является открытым/фоновым/неактивным application(_:didReceiveRemoteNotification:fetchCompletionHandler:)