Це добре зношений пост ... але все ще не вистачає фактичного рішення проблеми (на що вказується в різних коментарях).
Початкове запитання стосується виявлення, коли додаток було запущено
/ відкрито з натисненого повідомлення, наприклад, користувач натискає на сповіщення. Жодна з відповідей насправді не охоплює цю справу.
Причину можна побачити в потоці викликів, коли надходить повідомлення, application:didReceiveRemoteNotification...
отримує виклик, коли повідомлення отримано І знову, коли користувач натискає сповіщення. Через це ви не можете зрозуміти, просто подивившись на UIApplicationState
те, як користувач натиснув його.
Крім того, вам більше не потрібно обробляти ситуацію "холодного запуску" програми, application:didFinishLaunchingWithOptions...
як application:didReceiveRemoteNotification...
викликається знову після запуску в iOS 9+ (можливо, також 8).
Отже, як ви можете сказати, чи натиснути користувач запустив ланцюжок подій? Моє рішення - позначити час, коли програма починає виходити з фону або холодного початку, а потім перевірити цей час application:didReceiveRemoteNotification...
. Якщо вона менше 0,1 с, то ви можете бути впевнені, що натискання спрацьовує при запуску.
Швидкий 2.x
class AppDelegate: UIResponder, UIApplicationDelegate {
var wakeTime : NSDate = NSDate() // when did our application wake up most recently?
func applicationWillEnterForeground(application: UIApplication) {
// time stamp the entering of foreground so we can tell how we got here
wakeTime = NSDate()
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// ensure the userInfo dictionary has the data you expect
if let type = userInfo["type"] as? String where type == "status" {
// IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
if application.applicationState != UIApplicationState.Background && NSDate().timeIntervalSinceDate(wakeTime) < 0.1 {
// User Tap on notification Started the App
}
else {
// DO stuff here if you ONLY want it to happen when the push arrives
}
completionHandler(.NewData)
}
else {
completionHandler(.NoData)
}
}
}
Швидкий 3
class AppDelegate: UIResponder, UIApplicationDelegate {
var wakeTime : Date = Date() // when did our application wake up most recently?
func applicationWillEnterForeground(_ application: UIApplication) {
// time stamp the entering of foreground so we can tell how we got here
wakeTime = Date()
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// ensure the userInfo dictionary has the data you expect
if let type = userInfo["type"] as? String, type == "status" {
// IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
if application.applicationState != UIApplicationState.background && Date().timeIntervalSince(wakeTime) < 0.1 {
// User Tap on notification Started the App
}
else {
// DO stuff here if you ONLY want it to happen when the push arrives
}
completionHandler(.newData)
}
else {
completionHandler(.noData)
}
}
}
Я перевірив це для обох випадків (додаток у фоновому режимі, програма не працює) на iOS 9+ і це працює як шарм. 0,1s теж досить консервативний, фактичне значення ~ 0,002s, тому 0,01 також добре.