[英]When a remote notification is received, how to know whether the app is active at that time?
[英]How to know when app received notification and when user clicked on notification in iOS
我知道有很多关于这个主题的文章,但我找不到正确的答案。
有没有办法知道用户何时收到远程通知以及用户点击iOS 8上的一个。我想知道这一点,因为当我收到它时我想保存它,当用户点击它时我想打开一些观点。
我找到了这个答案https://stackoverflow.com/a/16393957/1241217,但问题是当用户在应用程序中并打开通知中心并点击其中一个时,该应用程序不是非活动状态而不是在后台。
我也找到了这个答案https://stackoverflow.com/a/12937568/1241217,但我知道只有当应用程序被杀死并从新启动时才会运行。
我也不想这样做https://stackoverflow.com/a/32079458/1241217,因为我需要检测何时收到通知。
那么有一种方法可以知道用户是否只点击了通知。 据我所知,它必须在didReceiveRemoteNotification中完成,但我不知道如何将它们分开。 我需要在iOS 10之前得到答案,因为应用目标是iOS 8。
我的解决方案
正如我在Shabbir Ahmad的评论中写道的那样,我的解决方案是记住应用程序确实生效的日期和收到通知的日期。 如果这个日期之间的差异是一秒或更短,我接受了当用户点击通知时。
您必须实现UNUserNotificationCenterDelegate
及其方法userNotificationCenter(_:willPresent:withCompletionHandler:)
userNotificationCenter(_:didReceive:withCompletionHandler:)
userNotificationCenter(_:willPresent:withCompletionHandler:)
和userNotificationCenter(_:didReceive:withCompletionHandler:)
,当用户点击通知时会调用它。 在willPresent:
您必须使用一个选项调用completionHandler
,该选项将指示在应用程序处于前台时通知到达时应该发生的情况。
注册这样的代表很容易:
UNUserNotificationCenter.current().delegate = self
例如:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(UNNotificationPresentationOptions.alert)
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let userInfo = userInfo as? [String: Any] {
// TODO: implement your logic
// just don't forget to dispatch UI stuff on main thread
}
}
您可以通过AppDelegate
实现该委托,也可以通过任何NSObject
实现该委托,我会使用后者来保持AppDelegate
尽可能干净。
PS:当然,这假设您已被用户授予权限( UNUserNotificationCenter.current().requestAuthorization(options:completionHandler:)
)并且您已注册接受通知( UIApplication.shared.registerForRemoteNotifications()
)。
阅读更多调度和处理本地通知 ,请参阅响应通知传递部分 - 虽然该部分是关于本地通知的,但它与远程通知完全相同(它们由同一个代理处理)。
当您在ios 10之前以及在前台时在后台模式中单击通知时,在以下两种情况下,您的下方将调用,
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
所以你可以区分行为,首先你在AppDelegate
类中分配一个布尔变量,如下所示:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var isUserTapOnNotification = false
之后,使true
isUserTapOnNotification
在
func applicationWillEnterForeground(_ application: UIApplication) {
isUserTapOnNotification = tue
}
因为当您点击通知栏时,您的应用程序将进入前台, applicationWillEnterForeground
将首先调用,之后您的didReceiveRemoteNotification
将调用:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if #available(iOS 10.0, *) {
//do nothing
}else { //<ios 10
if isUserTapOnNotification == true {//when app is in background and user tap on notification bar
//do action whatever you want
} else { //when user is in foreground and notification came,
//before ios10,notification bar not display in foreground mode,So you can show popup by using userInfo
}
}
在此之后, applicationDidBecomeActive
将调用并将您的isUserTapOnNotification
重置为false
如下所示:
func applicationDidBecomeActive(_ application: UIApplication) {
isUserTapOnNotification = false
}
我希望这个答案会对你有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.