이것은 잘 착용 된 게시물입니다 ...하지만 여전히 다양한 의견에서 지적한 것처럼 문제에 대한 실제 해결책 이 누락되었습니다 .
원래 질문은 푸시 알림에서 앱이 언제 시작
/ 열렸 는지 감지하는 것입니다 ( 예 : 사용자가 알림을 탭함). 실제로이 사례에 대한 답변은 없습니다.
알림이 도착하면 통화 흐름에서 이유를 확인할 수 있습니다. application:didReceiveRemoteNotification...
통지가 수신 될 때 호출되는 및 통지는 사용자가 탭하면 다시. 이 때문에 UIApplicationState
사용자가 탭을 보았을 때 알 수 없습니다 .
또한 iOS 9 이상 (아마도 8)에서 시작한 후 다시 호출 되는 application:didFinishLaunchingWithOptions...
것처럼 앱의 '콜드 스타트'상황을 더 이상 처리 할 필요가 없습니다 application:didReceiveRemoteNotification...
.
그렇다면 사용자 탭이 이벤트 체인을 시작했는지 어떻게 알 수 있습니까? 내 해결책은 앱이 백그라운드 또는 콜드 스타트에서 나오기 시작하는 시간을 표시 한 다음 그 시간을 확인하는 것입니다 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.1도 상당히 보수적이며 실제 값은 ~ 0.002s이므로 0.01도 좋습니다.