La notificación remota UIBackgroundMode de iOS no funciona en 4G

Estoy probando notifications push con contenido disponible = 1, y no parecen ser entregadas a la aplicación en segundo plano a less que esté en Wi-Fi.

Tengo una statement de logging simple al comienzo del controller de notifications push:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^) (UIBackgroundFetchResult))completionHandler { NSLog(@"Notification received: %@", userInfo); completionHandler(UIBackgroundFetchResultNewData); } 

Aquí está mi testing:

  1. Ejecuta la aplicación, luego presiona el button de inicio para poner la aplicación en segundo plano.
  2. Envía una notificación push con contenido disponible = 1
  3. Mira los loggings de la console

En Wi-Fi, el logging de la console muestra la notificación. Si voy a Configuración y apago Wi-Fi, cambiando a 4G, las notifications ya no aparecen en el logging (aunque se deslizan en la parte superior de la pantalla, por lo que sé que están siendo entregadas).

No hay loggings de lockings, y la notificación se registra si toco manualmente en ella. Además, este problema NO ocurre si estoy depurando la aplicación en Xcode. (es decir, si estoy depurando en Xcode, la aplicación recibirá la notificación en segundo plano en 4G). ¿Alguien más ha experimentado este comportamiento? ¿O estoy haciendo algo mal?

EDITAR : Para ser específico: de acuerdo con mis testings, si las siguientes condiciones son verdaderas, no se llamará al método de delegado de notificación remoto anterior:

  1. La aplicación se ejecuta en segundo plano
  2. El teléfono está en networking LTE, no está conectado a Wi-Fi.
  3. La aplicación NO se está ejecutando en el depurador Xcode
  4. El teléfono recibe la notificación con contenido disponible = 1.

Sin embargo, si se elimina la condición 2 (es decir, el teléfono está conectado a Wi-Fi), se llamará al controller.

Prueba el siguiente código:

 // AppDelegate.h @class ViewController; @interface AppDelegate : UIResponder <UIApplicationDelegate> { NSString *DeviceToken; NSMutableDictionary *App_Messages; NSString *Longitude,*Latitude; NSMutableDictionary * badge; } @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) ViewController *viewcontrollervc; @property (strong, nonatomic) UINavigationController *navcontroller; @property (nonatomic,retain)NSMutableDictionary *badge; @property (nonatomic,retain)NSString *DeviceToken; 

 // AppDelegate.m #import "ViewController.h" @implementation AppDelegate @synthesize badge,DeviceToken; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; self.viewcontrollervc = [[ViewController alloc]initWithNibName:@"ViewController" bundle:nil]; self.navcontroller = [[UINavigationController alloc]initWithRootViewController:self.viewcontrollervc]; self.window.rootViewController = self.navcontroller; self.navcontroller.navigationBarHidden = YES; //Notification [[UIApplication shanetworkingApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; NSDictionary * remoteNotificationObj = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"]; if (remoteNotificationObj) { [self performSelector:@selector(handleRemoteNotificationWithUserInfo:) withObject:remoteNotificationObj afterDelay:3.0]; } [self.window makeKeyAndVisible]; return YES; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [self handleRemoteNotificationWithUserInfo:userInfo]; } -(void)handleRemoteNotificationWithUserInfo:(NSDictionary *)userInfo { NSLog(@"userInfo - %@",userInfo); NSDictionary *alertData = [userInfo objectForKey:@"aps"]; NSDictionary *returnDatalert=[alertData objectForKey:@"alert"]; NSString *alertmsg=[returnDatalert objectForKey:@"body"]; NSLog(@"alertmsg %@",alertmsg); self.badge = [NSMutableDictionary dictionaryWithDictionary:[alertData objectForKey:@"badge"]]; NSString *notificationtype=[badge objectForKey:@"fnct"]; NSLog(@"%@",notificationtype); } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken); NSString *dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; dt = [dt stringByReplacingOccurrencesOfString:@" " withString:@""]; self.DeviceToken=dt; NSLog(@"~~~~devToken(dv)=%@",deviceToken); } - (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error { NSLog(@"Failed to get token, error: %@", error); } 

Según los comentarios de un comentarista aquí y las repetidas testings en múltiples dispositivos, esto parece ser un error (o comportamiento previsto) en iOS.

Para mí, funcionaba en Wi-Fi y en 4G (LTE forzado en la configuration celular), pero no funcionaba en LTE.

Actualización: después de una extensa debugging, encontré este problema relacionado con dos cosas para mí cuando estaba en LTE. Uno es el poder Descubrí si el iPhone estaba conectado a la panetworking, la aplicación se despertó como se esperaba. Si no estaba conectado, la aplicación no se despertó en respuesta a content-available = 1. En segundo lugar, estaba la configuration del dispositivo. A pesar de que todas las configuraciones relacionadas se configuraron correctamente, hacer un 'Restablecer todos los ajustes' solucionó el problema para mí.

Suponiendo que esto no es un error de Apple, creo que iOS desarrolla un perfil de energía para un determinado identificador de aplicación; opta, bajo ciertas circunstancias (estado de la networking, estado de la batería, etc.) para no despertar las aplicaciones que utilizan ciclos de background excesivos. Por ejemplo, usar beginBackgroundTaskWithExpirationHandler incorrectamente, haciendo que una aplicación permanezca activa en segundo plano y forzando a iOS a caducar. Incluso la fijación de un uso excesivo de backgrounds podría no corregir el problema, ya que iOS ya ha determinado que su aplicación es una fuente de información. Esto explicaría el "Rest all Settings" para aclarar el problema para mí.

Lamentablemente, todo esto es solo una suposition basada en 2-3 días de debugging de este problema y probablemente nunca sabremos con certeza, ya que hay tantas variables en juego con las notifications push, por no mencionar la documentation vaga y variable.