首页 文章

iOS推送通知:当应用程序处于后台时,如何检测用户是否点击了通知?

提问于
浏览
90

关于这个主题有很多stackoverflow线程,但我仍然没有找到一个好的解决方案 .

如果应用程序不在后台,我可以在 application:didFinishLaunchingWithOptions: 中查看 launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] 以查看它是否从通知中打开 .

如果应用程序在后台,所有帖子建议使用 application:didReceiveRemoteNotification: 并检查应用程序状态 . 但是当我进行实验时(以及此API的名称建议),此方法在收到通知时被调用,而不是被点击 .

所以问题是,如果应用程序启动然后后台运行,并且您知道从 application:didReceiveNotification 收到通知( application:didFinishLaunchWithOptions: 获胜't trigger at this point), how do you know if user resumed the app from by tapping the notification or just tapping the app icon? Because if the user tapped the notification, the expectation is to open the page mentioned in that notification. Otherwise it shouldn' t .

我可以使用 handleActionWithIdentifier 进行自定义操作通知,但这仅在轻触自定义操作按钮时触发,而不是在用户点击通知主体时触发 .

谢谢 .

编辑:

在阅读下面的一个答案之后,我想通过这种方式我可以澄清我的问题:

我们如何区分这两种情况:

(A)1.app转到后台; 2.收到通知; 3.用户点击通知; 4. app进入前台

(B)1.app转到后台; 2.收到通知; 3.用户忽略通知并稍后点击应用程序图标; 4. app进入前台

由于在步骤2中两种情况都触发 application:didReceiveRemoteNotification: .

或者,应该仅在步骤3中为(A)触发 application:didReceiveRemoteNotification: ,但我以某种方式将我的应用程序配置错误,所以我在第2步看到了它?

8 回答

  • 4

    在我的情况下,背景模式OFF没有任何区别 . 但是当应用程序被暂停并且用户点击了通知时,我可以在此回调方法中处理这种情况:

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
    
    }
    
  • 3

    根据iOS / XCode: how to know that app has been launched with a click on notification or on springboard app icon?,您必须在didReceiveLocalNotification中检查应用程序状态,如下所示:

    if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
    {
        // user has tapped notification
    }
    else
    {
        // user opened app from app icon
    }
    

    虽然它对我来说没有任何意义,但似乎有效 .

  • -6

    如果有人想在swift 3.0中使用它

    switch application.applicationState {
        case .active:
            //app is currently active, can update badges count here
            break
        case .inactive:
            //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
            break
        case .background:
            //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
            break
        default:
            break
        }
    
  • 58

    如果您选择“后台模式”>“远程通知”==是,点击通知事件将到达:

    -(void)userNotificationCenter:(UNUserNotificationCenter *)center **didReceiveNotificationResponse**:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler.
    

    它帮助了我 . 请享受 :)

  • 14

    我也遇到了这个问题 - 但是在iOS 11上使用了新的 UserNotifications 框架 .

    这对我来说就像这样:

    • 新发布: application:didFinishLaunchingWithOptions:

    • 在前景中收到: application:didReceiveRemoteNotification:fetchCompletionHandler:

    • 在后台收到: userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:

  • 19

    好的,我终于明白了 .

    在目标设置➝功能选项卡➝后台模式中,如果您选中"Remote Notifications", application:didReceiveRemoteNotification: 将在通知到达时立即触发(只要应用程序在后台),在这种情况下无法判断用户是否将点按通知 .

    如果取消选中该框,则仅在您点击通知时才会触发 application:didReceiveRemoteNotification: .

    检查此框会改变其中一个应用程序委托方法的行为方式,这有点奇怪 . 如果选中此框会更好,Apple会使用两种不同的委托方法进行通知接收和通知点击 . 我认为大多数开发人员总是想知道是否有通知 .

    希望这对遇到此问题的任何其他人都有帮助 . Apple也没有明确记录here所以我花了一段时间才弄明白 .

    enter image description here

  • 81

    我一直在寻找和你一样的东西,并且实际上找到了一个不需要远程通知的解决方案 .

    要检查用户是否已点击,或应用程序处于后台或处于活动状态,您只需检查应用程序状态

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
    
        if(application.applicationState == UIApplicationStateActive) {
    
            //app is currently active, can update badges count here
    
        }else if(application.applicationState == UIApplicationStateBackground){
    
            //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
    
        }else if(application.applicationState == UIApplicationStateInactive){
    
            //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
    
        }
    

    欲了解更多信息:

    UIKit Framework Reference > UIApplication Class Reference > UIApplicationState

  • 1

    您可以配置推送通知的有效负载,以便在应用程序处于后台时调用应用程序委托的 application:didReceiveRemoteNotification:fetchCompletionHandler: 方法 . 您可以在此设置一些标志,以便下次用户启动您的应用程序时,您可以执行操作 .

    从apple的文档中,您应该使用此方法下载与推送通知相关的新内容 . 此外,为了使其工作,您必须从后台模式启用远程通知,并且您的推送通知有效负载必须包含 content-available 密钥,其值设置为1.有关详细信息,请参阅使用推送通知从apple doc here启动下载部分 .

    另一种方法是在推送通知有效负载中使用徽章计数 . 因此,下次启动应用程序时,您可以检查应用程序徽章计数 . 如果其大于零,则从服务器执行操作和零/清除徽章计数也 .

    希望这对你有所帮助 .

相关问题