Dies ist ein abgenutzter Beitrag ... aber es fehlt immer noch eine tatsächliche Lösung für das Problem (wie in den verschiedenen Kommentaren ausgeführt).
Bei der ursprünglichen Frage geht es darum, anhand einer Push-Benachrichtigung zu erkennen, wann die App gestartet
/ geöffnet wurde , z. B. wenn ein Benutzer auf die Benachrichtigung tippt. Keine der Antworten deckt diesen Fall tatsächlich ab.
Der Grund kann im Anrufverlauf gesehen werden, wenn eine Benachrichtigung eintrifft. application:didReceiveRemoteNotification...
wird aufgerufen, wenn die Benachrichtigung empfangen wird UND erneut, wenn der Benutzer auf die Benachrichtigung tippt. Aus diesem Grund können Sie nicht erkennen, UIApplicationState
ob der Benutzer darauf getippt hat.
Außerdem müssen Sie die Situation eines Kaltstarts der App nicht mehr bewältigen, application:didFinishLaunchingWithOptions...
wie application:didReceiveRemoteNotification...
sie nach dem Start in iOS 9+ erneut aufgerufen wird (möglicherweise auch 8).
Wie können Sie also feststellen, ob der Benutzer die Ereigniskette gestartet hat? Meine Lösung besteht darin, die Zeit zu markieren, zu der die App aus dem Hintergrund oder dem Kaltstart herauskommt, und diese Zeit dann einzuchecken application:didReceiveRemoteNotification...
. Wenn es weniger als 0,1 Sekunden ist, können Sie ziemlich sicher sein, dass der Tipp den Start ausgelöst hat.
Swift 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)
}
}
}
Swift 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)
}
}
}
Ich habe dies für beide Fälle (App im Hintergrund, App läuft nicht) unter iOS 9+ getestet und es funktioniert wie ein Zauber. 0,1s ist auch ziemlich konservativ, der tatsächliche Wert ist ~ 0,002s, also ist 0,01 ebenfalls in Ordnung.