これは使い古された投稿ですが、まだ問題に対する実際の解決策がありません(さまざまなコメントで指摘されています)。
元の質問は、プッシュ通知からアプリがいつ起動
/ 開かれたかを検出することです。たとえば、ユーザーが通知をタップします。実際にはこのケースをカバーする回答はありません。
理由は、通知が到着したときにコールフローで確認できます。 application:didReceiveRemoteNotification...
通知が受信されたとき、およびユーザーが通知をタップしたときに再び呼び出されます。このためUIApplicationState
、ユーザーがタップしたかどうかを見ただけではわかりません。
また、中にアプリの「コールドスタート」の状況を処理するために、あなたはもはや必要application:didFinishLaunchingWithOptions...
としては、application:didReceiveRemoteNotification...
iOSの9+(多分8と同様)で起動した後、再び呼び出されません。
では、ユーザーが一連のイベントを開始したかどうかをどのように確認できますか?私の解決策は、アプリがバックグラウンドまたはコールドスタートから抜け出す時間をマークし、その時間をで確認することapplication:didReceiveRemoteNotification...
です。0.1秒未満の場合は、タップによって起動がトリガーされたことを確認できます。
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)
}
}
}
スウィフト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でも問題ありません。