如何知道应用程序何时收到通知以及用户何时在iOS中点击通知

问题描述 投票:4回答:2

我知道有很多关于这个主题的文章,但我找不到正确的答案。

有没有办法知道用户何时收到远程通知以及用户点击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的评论中所写的那样,我的解决方案是记住申请确实生效的日期和收到通知的日期。如果这个日期之间的差异是一秒或更短,我接受了当用户点击通知时。

ios push-notification notifications apple-push-notifications
2个回答
2
投票

你必须实现UNUserNotificationCenterDelegate及其方法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尽可能干净。

P.S。:当然,这假设您已被用户授权(UNUserNotificationCenter.current().requestAuthorization(options:completionHandler:))并且您已注册接受通知(UIApplication.shared.registerForRemoteNotifications())。

Scheduling and Handling Local Notifications中阅读更多内容,响应通知的传递 - 虽然该部分是关于本地通知的,但对于远程通知则完全相同(它们由同一个代理处理)。


2
投票

当您在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
    }

我希望这个答案会对你有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.