Bu iyi yıpranmış bir yazı ... ama yine de soruna gerçek bir çözüm eksik (çeşitli yorumlarda belirtildiği gibi).
Orijinal soru, uygulamanın bir push bildiriminden ne zaman başlatıldığını
/ açıldığını tespit etmektir , örneğin bir kullanıcı bildirime hafifçe vurur. Cevapların hiçbiri bu davayı kapsamıyor.
Nedeni, bir bildirim geldiğinde çağrı akışında görülebilir, application:didReceiveRemoteNotification...
bildirim alındığında çağrılan VE bildirim kullanıcı tarafından dokunulduğunda tekrar. Bu nedenle UIApplicationState
, kullanıcının ona dokunup dokunmadığına bakarak söyleyemezsiniz .
Ayrıca, uygulamanın bir 'soğuk başlangıç' bir durumun üstesinden gelmek için artık ihtiyacımız application:didFinishLaunchingWithOptions...
olarak application:didReceiveRemoteNotification...
(belki 8 sıra) 9+ iOS'taki başlatılması sonra tekrar çağrılır.
Peki, kullanıcının hafifçe vurma olay zincirini başlattı olmadığını nasıl anlarsınız? Benim çözüm, uygulamanın arka plandan veya soğuk başlangıçtan çıkmaya başladığı zamanı işaretlemek ve ardından bu zamanı kontrol etmektir application:didReceiveRemoteNotification...
. 0.1 saniyeden azsa, musluğun başlangıcı tetiklediğinden emin olabilirsiniz.
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)
}
}
}
Hızlı 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)
}
}
}
Bunu her iki durumda da test ettim (arka planda uygulama, uygulama çalışmıyor) ve bir cazibe gibi çalışıyor. 0.1s de oldukça muhafazakardır, gerçek değer ~ 0.002s'dir, bu nedenle 0.01 de iyidir.