react ios objective-c swift3 apple-push-notifications

push notifications ios react native



didReceiveRemoteNotification no llamado, iOS 10 (8)

Es un error de iOS. Se solucionará en iOS 10.1. Pero solo espere la versión 10.1 en octubre en lugar de implementar una nueva biblioteca y elimínela más tarde.

https://forums.developer.apple.com/thread/54322

En iOS 9.3, se didReceiveRemoteNotification método didReceiveRemoteNotification en las dos ocasiones siguientes.

1) Cuando se recibe la notificación push 2) Cuando el usuario inicia la aplicación tocando la notificación.

Pero en iOS 10, noto que el método didReceiveRemoteNotification NO se didReceiveRemoteNotification cuando el usuario inicia la aplicación tocando la notificación. Se llama solo cuando se recibe la notificación. Por lo tanto, no puedo realizar ninguna otra acción después de que la aplicación se inicie desde la notificación.

¿Cuál debería ser la solución para esto? ¿Alguna idea?


Por cierto, este problema parece estar solucionado en iOS 10.1. Probé mi aplicación en 10.1, todo funciona bien


Versión de trabajo iOS 11, Swift 4, Xcode 9 . Simplemente copie y pegue el siguiente código en AppDelegate.

import UIKit import UserNotifications @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { if #available(iOS 10, *) { // iOS 10 support //create the notificationCenter let center = UNUserNotificationCenter.current() center.delegate = self // set the type as sound or badge center.requestAuthorization(options: [.sound,.alert,.badge]) { (granted, error) in if granted { print("Notification Enable Successfully") }else{ print("Some Error Occure") } } application.registerForRemoteNotifications() } else if #available(iOS 9, *) { // iOS 9 support UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } else if #available(iOS 8, *) { // iOS 8 support UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } else { // iOS 7 support application.registerForRemoteNotifications(matching: [.badge, .sound, .alert]) } return true } //get device token here func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() print("Registration succeeded!") print("Token: ", token) //send tokens to backend server } //get error here func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Registration failed!") } //get Notification Here below ios 10 func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) { // Print notification payload data print("Push notification received: /(data)") } //This is the two delegate method to get the notification in iOS 10.. //First for foreground @available(iOS 10.0, *) 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)") } //Second for background and close @available(iOS 10.0, *) 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)") } }


Yo tuve el mismo problema. -application:didReceiveRemoteNotification:fetchCompletionHandler: banner de notificación, pero -application:didReceiveRemoteNotification:fetchCompletionHandler: no se llamó al método. La solución para mí que funcionó fue agregar la implementación de - application:didReceiveRemoteNotification: method y reenviar la llamada a -application:didReceiveRemoteNotification:fetchCompletionHandler: ::

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

Source


Código Swift :

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.currentNotificationCenter() center.delegate = self } // ... return true } @available(iOS 10.0, *) public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { print(response.notification.request.content.userInfo) } @available(iOS 10.0, *) public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { print(notification.request.content.userInfo) }


swift 4, si está utilizando ios 11 o una versión de xcode superior a 9.0, entonces debe haber utilizado el método delegado UNUserNotification para llamar a didReceiveRemoteNotification

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { //Your code to handle events }


tipo converson

para Swift3

-

para muestra ver this

importar el marco de UserNotifications y agregar UNUserNotificationCenterDelegate en Appdelegate

import UserNotifications @UIApplicationMain class 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!") }

recibir las notificaciones utilizando estos delegados

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! UINavigationController let notificationSettingsVC = NotificationSettingsViewController() navController.pushViewController(notificationSettingsVC, animated: true) }

para más información puede ver en la Reference API de Apple

C objetivo

AppDelegate.h tiene estas líneas:

Paso 1

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

Paso 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)

Paso 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; }

Esto se activará como resultado de llamar a registerForRemoteNotifications:

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

Luego, cuando un usuario toca una notificación, se dispara:

Esto se activará en iOS 10 cuando la aplicación esté en primer plano o en segundo plano, pero no esté cerrada

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

o usar

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

Luego, para iOS 10, estos dos métodos:

- (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 y IOS 12.

Si bien puede haber múltiples razones (ya mencionadas en otras respuestas) por las cuales este problema podría ocurrir, en mi caso personal la solución estaba relacionada con la carga útil al enviar la notificación push:

Debe establecer la clave "contenido disponible" en la carga útil de json en 1.

p.ej:

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