【问题标题】:didReceiveRemoteNotification called twicedidReceiveRemoteNotification 调用了两次
【发布时间】:2016-04-27 11:50:00
【问题描述】:

我已经在我的应用中实现了推送通知。

当我的应用程序在前台时,我的应用程序工作正常。

但当应用程序在后台或被杀死时,我的didReceiveRemoteNotification 会调用两次。

我做了一个处理推送通知的通用方法,并从didFinishLaunchingWithOptionsdidReceiveRemoteNotification调用这个方法

这是我的实现:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  NSDictionary *pushDictionary = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
  if (pushDictionary) {
    [self customPushHandler:pushDictionary];
  }

  return YES;

}

还有:

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


         [self customPushHandler:userInfo];

 }

与:

 - (void) customPushHandler:(NSDictionary *)notification {

     // Code to push ViewController

         NSLog(@"Push Notification"); //Got it two times when Clicked in notification banner

   }

当我的应用程序运行时,ViewController 被推送一次。当我从通知横幅打开我的应用程序时,我的屏幕会被推送两次。

我在customPushHandler 中放置了一个 NSLog,当应用程序处于前台时我得到了一次,当我从通知横幅启动它时得到了两次。

我的代码有什么问题?

【问题讨论】:

标签: ios objective-c iphone push-notification xcode6


【解决方案1】:

"当应用程序在后台时,该方法会被调用两次,一次是在您收到推送通知时,另一次是在您点击该通知时。"

如果应用处于后台,您可以验证应用状态并忽略收到的通知。

解决方案:Remote notification method called twice

Swift 4 代码:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        if (application.applicationState == .background) {
            completionHandler(.noData)
            return
        }

    // logic
    // call completionHandler with appropriate UIBackgroundFetchResult
}

【讨论】:

    【解决方案2】:

    每当您使用 backgroundFetch 进行远程通知时,请为此添加一个完成处理程序。

    - (void)application:(UIApplication *)application
       didReceiveRemoteNotification:(NSDictionary *)userInfo
       fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
    
        [self customPushHandler:userInfo];
    
        completionHandler(UIBackgroundFetchResultNewData)
    }
    

    【讨论】:

      【解决方案3】:

      didReceiveRemoteNotification 中检查这一条件,例如 如果您在应用处于后台时点击通知。这样,您可以避免被调用两次。

       - (void)application:(UIApplication *)application
      didReceiveRemoteNotification:(NSDictionary *)userInfo
      fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
            UIApplicationState state = [[UIApplication sharedApplication] applicationState];
            if (state == UIApplicationStateBackground || state == UIApplicationStateInactive || state == UIApplicationStateForeground || state == UIApplicationStateActive)
            {
                //Do checking here.
                [self customPushHandler:userInfo];
            }
      }
      

      检查我是否已编辑我的答案。

      【讨论】:

      • no inside if 条件只有你必须调用。因为如果应用程序是从后台打开的,则应该调用此方法。如果应用程序从 didfinishlauch 方法终止,则应调用您的处理程序。
      • 你没有明白我的意思。我也从didFinishLaunchingWithOptions 调用customPushHandler 方法。如果我使用你的代码,我的customPushHandler 将始终被调用两次,当我的应用程序处于前台时,我的customPushHandler 将永远不会被调用
      • 应用程序不会一次调用这两个方法。如文档所述,它们具有不同的功能。取而代之的是 if (pushDictionary) 像这样检查 if (pushDictionary ! = nil)。或在这两种方法中记录 pushDictionary。如果你得到相同的价值或零?
      【解决方案4】:

      检查当前导航堆栈中的顶视图控制器,如:

      if(![self.navigationController.topViewController isKindOfClass:[MyClass class]]) {
      
                 //code for pushing new controller
      
       }
      

      【讨论】:

        猜你喜欢
        • 2013-02-04
        • 2017-06-25
        • 2013-01-21
        • 2012-09-08
        • 2019-02-27
        • 1970-01-01
        • 2019-12-04
        • 2018-09-15
        • 2012-10-10
        相关资源
        最近更新 更多