didReceiveRemoteNotification not called, iOS 10 didReceiveRemoteNotification not called, iOS 10 objective-c objective-c

didReceiveRemoteNotification not called, iOS 10


type converson

enter image description here

for Swift3

enter image description here

-

for sample see this

import the UserNotifications framework and add the UNUserNotificationCenterDelegate in Appdelegate

import UserNotifications@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {    // Override point for customization after application launch.    //create the notificationCenter    let center  = UNUserNotificationCenter.current()    center.delegate = self    // set the type as sound or badge    center.requestAuthorization(options: [.sound,.alert,.badge,  .providesAppNotificationSettings]) { (granted, error) in        // Enable or disable features based on authorization        }        application.registerForRemoteNotifications()    return true} func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // let chars = UnsafePointer<CChar>((deviceToken as NSData).bytes)  var token = ""  for i in 0..<deviceToken.count {//token += String(format: "%02.2hhx", arguments: [chars[i]])   token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])  }  print("Registration succeeded!")  print("Token: ", token) } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {  print("Registration failed!") }

receive the Notifications using this delegates

 func userNotificationCenter(_ center: UNUserNotificationCenter,  willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ options:   UNNotificationPresentationOptions) -> Void) {    print("Handle push from foreground")    // custom code to handle push while app is in the foreground    print("\(notification.request.content.userInfo)") }func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {    print("Handle push from background or closed")    // if you set a member variable in didReceiveRemoteNotification, you  will know if this is from closed or background    print("\(response.notification.request.content.userInfo)")}func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) {let navController = self.window?.rootViewController as! UINavigationControllerlet notificationSettingsVC = NotificationSettingsViewController()navController.pushViewController(notificationSettingsVC, animated: true)}

for more Information you can see in Apple API Reference


objective C

AppDelegate.h has these lines:

Step-1

//Add Framework in your project "UserNotifications"#import <UserNotifications/UserNotifications.h>  @interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>  

Step-2

AppDelegate.m

  // define macro  #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)    #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)  

Step-3

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {application.applicationIconBadgeNumber = 0;    if( SYSTEM_VERSION_LESS_THAN( @"10.0" ) ) {          [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound |    UIUserNotificationTypeAlert | UIUserNotificationTypeBadge |  UIUserNotificationTypeprovidesAppNotificationSettings) categories:nil]];          [[UIApplication sharedApplication] registerForRemoteNotifications];          //if( option != nil )          //{          //    NSLog( @"registerForPushWithOptions:" );          //}      } else {        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];        center.delegate = self;        [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {        if( !error ) {            // required to get the app to do anything at all about push notifications              [[UIApplication sharedApplication] registerForRemoteNotifications];            NSLog( @"Push registration success." );          } else {            NSLog( @"Push registration FAILED" );              NSLog( @"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription );              NSLog( @"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );          }        }];    }    return YES;}

This will fire as a result of calling registerForRemoteNotifications:

 - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken  {  // custom stuff we do to register the device with our AWS middleman   }

Then, when a user taps a notification, this fires:

This will fire in iOS 10 when the app is foreground or background, but not closed

 -(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void    (^)(UIBackgroundFetchResult))completionHandler    {  // iOS 10 will handle notifications through other methods  if( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO( @"10.0" ) )  {    NSLog( @"iOS version >= 10. Let NotificationCenter handle this one." );   // set a member variable to tell the new delegate that this is background    return;  }  NSLog( @"HANDLE PUSH, didReceiveRemoteNotification: %@", userInfo );  // custom code to handle notification content  if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive )  {    NSLog( @"INACTIVE" );    completionHandler( UIBackgroundFetchResultNewData );  }  else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground )  {    NSLog( @"BACKGROUND" );    completionHandler( UIBackgroundFetchResultNewData );  }  else  {    NSLog( @"FOREGROUND" );    completionHandler( UIBackgroundFetchResultNewData );  }  }  

or use

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

Then for iOS 10, these two methods:

- (void)userNotificationCenter:(UNUserNotificationCenter *)center      willPresentNotification:(UNNotification *)notification    withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler      {    NSLog( @"Handle push from foreground" );    // custom code to handle push while app is in the foreground      NSLog(@"%@", notification.request.content.userInfo);   }  - (void)userNotificationCenter:(UNUserNotificationCenter *)center  didReceiveNotificationResponse:(UNNotificationResponse *)response    withCompletionHandler:(void (^)())completionHandler     {       NSLog( @"Handle push from background or closed" );       // if you set a member variable in didReceiveRemoteNotification, you  will know if this is from closed or background       NSLog(@"%@", response.notification.request.content.userInfo);    }      - (void)userNotificationCenter:(UNUserNotificationCenter *)center    openSettingsForNotification:(UNNotification *)notification{        Open notification settings screen in app   }


Swift 4 and IOS 12.

While there might be multiple reasons (Already mentioned on other answers) why this issue could happen, in my personal case the solution was related to the payload when sending the push notification:

You need to set the "content-available" key on the json payload to 1.

e.g:

{"aps":{"alert":"Test", "content-available":1, "badge":1,"sound":"default"}}


I had the same problem. Notification banner appeared, but -application:didReceiveRemoteNotification:fetchCompletionHandler: method was not called. The solution for me that worked was to add implementation of - application:didReceiveRemoteNotification: method and forward call to -application:didReceiveRemoteNotification:fetchCompletionHandler::

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

Source.