这是一篇陈旧的帖子......但它仍然缺少解决问题的实际解决方案(正如各种评论中所指出的那样)。
最初的问题是关于检测应用程序何时从推送通知启动
/打开,例如用户点击通知。没有一个答案实际上涵盖了这种情况。
原因可以在通知到达时的调用流程中看到,application:didReceiveRemoteNotification...
当收到通知并在用户点击通知时再次调用。因此,您无法仅通过查看UIApplicationState
用户是否点击它来判断。
此外,您不再需要处理在 iOS 9+(也可能是 8)启动后再次调用的应用application:didFinishLaunchingWithOptions...
程序“冷启动”的情况。application:didReceiveRemoteNotification...
那么,如何判断用户点击是否启动了事件链呢?我的解决方案是标记应用程序开始退出后台或冷启动的时间,然后在application:didReceiveRemoteNotification...
. 如果小于 0.1s,那么你可以很确定点击触发了启动。
斯威夫特 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 也可以。