8

I have implemented Push Notification in my App.

When my app is in the foreground then my app is working fine.

But when the app is in the background or is killed then my didReceiveRemoteNotification called two times.

I have made a common method for handling Push notification and calling this method from didFinishLaunchingWithOptions and didReceiveRemoteNotification

Here is my Implementation:

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

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

  return YES;

}

And :

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


         [self customPushHandler:userInfo];

 }

AND:

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

     // Code to push ViewController

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

   }

When my App is running then ViewController is pushed Once. And when I open my app From notification banner then My screen is pushed twice.

I placed a NSLog in customPushHandler and I got it one time when App is in foreground and Two time when I launch it from Notification banner.

What is issue in my code.?

Mayank Patel
  • 3,868
  • 10
  • 36
  • 59
Rahul
  • 5,594
  • 7
  • 38
  • 92
  • 1
    Refer http://stackoverflow.com/questions/22085234/didreceiveremotenotification-fetchcompletionhandler-open-from-icon-vs-push-not#comment51407901_22085855 – Avijit Nagare Jul 05 '16 at 09:36

4 Answers4

6

"When the app is in background, the method is called twice, once when you receive the push notification, and other time when you tap on that notification."

You can verify the application state and ignore the notification received if the app is in background.

Solution: Remote notification method called twice

Swift 4 code:

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
}
Michael Lima
  • 61
  • 1
  • 3
0

check this one condition in didReceiveRemoteNotification, like if you tap on notification while app is in background. By that way, you can avoid getting called twice.

 - (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];
      }
}

Check I have edited my answer.

RJV Kumar
  • 2,408
  • 1
  • 19
  • 28
  • no inside if condition only you have to call. Because if the app is opened from background, this method should get called. If the app is terminated then from didfinishlauch method, your handler should get called. – RJV Kumar Jan 21 '16 at 10:23
  • you are not geting my point. I am calling `customPushHandler` method from `didFinishLaunchingWithOptions` also.. If I use you code the my `customPushHandler` will be always called twice and when my app is in foreground then my `customPushHandler` will never be called – Rahul Jan 21 '16 at 12:08
  • Application won't call these two methods at a time. They have different functionalities as described by documentation. Instead of this, if (pushDictionary) check like this if (pushDictionary ! = nil). or log the pushDictionary in both methods. If you are getting same value or nil? – RJV Kumar Jan 21 '16 at 12:17
0

Check top view controller in current navigation stack like:

if(![self.navigationController.topViewController isKindOfClass:[MyClass class]]) {

           //code for pushing new controller

 }
Mayank Patel
  • 3,868
  • 10
  • 36
  • 59
0

Whenever you use backgroundFetch for remote notification, add a completion handler for that.

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

    [self customPushHandler:userInfo];

    completionHandler(UIBackgroundFetchResultNewData)
}
Varun
  • 759
  • 6
  • 12