除非应用程序从通知中恢复,否则不会调用 didReceiveRemoteNotification

Posted

技术标签:

【中文标题】除非应用程序从通知中恢复,否则不会调用 didReceiveRemoteNotification【英文标题】:didReceiveRemoteNotification Not Being Called Unless Application Resumed From Notification 【发布时间】:2015-12-04 12:26:25 【问题描述】:

标题解释了正在发生的事情。应用程序正在运行但已最小化。通知显示给用户。当用户点击通知时,应用程序被带到前台并输入方法 didReceiveRemoteNotification。但是,如果用户单击应用程序图标而不是恢复应用程序,则 didReceiveRemoteNotification 方法不会执行。

这是我的代码:

在 didFinishLaunchingWithOptions 中:

 //FOR ALLOWING NOTIFICATIONS
            let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
            UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
            UIApplication.sharedApplication().registerForRemoteNotifications()

 func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) 
        let deviceTokenStr = convertDeviceTokenToString(deviceToken)
        GlobalVariables.UserDefaults.setValue(deviceTokenStr,forKey: "Push_Notification_Reg_ID");
        RZLog.VIP("The PushNotification Device Token is: \(deviceTokenStr)")

    

    func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) 

        RZLog.Error(error.description)
    

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) 
        RZLog.Debug("A NEW NOTIFICATION HAS BEEN RECEIVED")
        //handle

                completionHandler(UIBackgroundFetchResult.NoData)
        
    

【问题讨论】:

通知的有效负载中有什么?有content-available: 吗? 我刚刚添加了“content-available”:“1”,哈哈,它起作用了。但现在它会被调用两次,以防我按下通知 【参考方案1】:

这是设计使然。当应用程序(在后台或前台)接收到远程通知时以及用户从通知启动应用程序时调用该方法。

如果用户点击应用程序图标,则只有

applicationWillEnterForeground:

applicationDidBecomeActive:

将被调用

【讨论】:

【参考方案2】:

不会在后台调用 didReceiveRemoteNotification。你应该使用

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 

    if(application.applicationState == UIApplicationStateInactive) 

    NSLog(@"Inactive");

    //Show the view with the content of the push

    completionHandler(UIBackgroundFetchResultNewData);

 else if (application.applicationState == UIApplicationStateBackground) 

    NSLog(@"Background");

    //Refresh the local model

    completionHandler(UIBackgroundFetchResultNewData);

 else 

    NSLog(@"Active");

    //Show an in-app banner

    completionHandler(UIBackgroundFetchResultNewData);



基本上didReceiveRemoteNotification只在以下场景中调用:

    点击推送通知横幅,应用程序进入前台并调用 didReceiveRemoteNotification。

    当应用程序在前台运行时,推送通知到达并调用 didReceiveRemoteNotification。

来自 Apple 文档: 如果推送通知到达时应用程序未运行,则该方法将启动应用程序并在启动选项字典中提供适当的信息。该应用程序不会调用此方法来处理该推送通知。相反,您的 application:willFinishLaunchingWithOptions: 或 application:didFinishLaunchingWithOptions: 方法的实现需要获取推送通知有效负载数据并做出适当的响应。

【讨论】:

以上是关于除非应用程序从通知中恢复,否则不会调用 didReceiveRemoteNotification的主要内容,如果未能解决你的问题,请参考以下文章

除非在 [重复] 之前打印条件,否则不会调用 if 语句

iOS 静默通知互联网连接

确定是不是从 FCM 通知调用活动

意图恢复先前暂停的活动(从通知中调用)

为 Firebase 通知创建消息头

除非用户登录,否则钥匙串不会从 Jenkins 脚本解锁