4G的iOS UIBackgroundMode远程通知不起作用

我正在使用content-available = 1testing推送通知,而且除非在Wi-Fi上,否则它们似乎不会在后台传送到应用程序。

我在推送通知处理程序的开始处有一个简单的日志语句:

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

这是我的testing:

  1. 运行应用程序,然后按主页button将应用程序放在后台。
  2. 使用content-available = 1发送推送通知
  3. 观看控制台日志

在Wi-Fi上,控制台日志显示通知。 如果我转到设置并closuresWi-Fi,切换到4G,通知不会再出现在日志中(虽然他们滑入屏幕的顶部,所以我知道他们正在交付)。

没有崩溃日志,如果手动点击它,通知就会被logging下来。 此外,如果我在Xcode中debugging应用程序,则不会发生此问题。 (即,如果我在Xcode中进行debugging,应用程序将在后台收到有关4G的通知)。 有没有其他人经历过这种行为? 还是我做错了什么?

编辑 :具体来说:根据我的testing,如果以下条件为真,那么上面的远程通知委托方法将不会被调用:

  1. 应用程序正在后台运行
  2. 手机在LTEnetworking上,未连接到Wi-Fi
  3. 应用程序不在Xcodedebugging器中运行
  4. 内容可用= 1的通知由电话接收

但是,如果条件2被删除(即手机连接到Wi-Fi),那么处理程序将被调用。

试试下面的代码:

 // 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 sharedApplication] 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); } 

基于来自评论者的反馈,并在多个设备上进行重复testing,这似乎是iOS上的一个错误(或预期行为)。

对我来说,它在Wi-Fi和4G上工作(LTE在蜂窝设置中被迫closures),但在LTE上不起作用。

更新:经过广泛的debugging后,我发现这个问题涉及到LTE上的两件事情。 一个是权力。 我发现,如果iPhone插入墙上,应用程序就像预期的那样被唤醒。 如果没有插入,则应用程序不会响应内容= 1而被唤醒。其次,是设备设置。 即使每个相关设置都设置正确,但执行“重置所有设置”会为我解决问题。

假设这不是苹果的错误,我猜测是iOS为给定的应用程序标识符开发了一个强大的configuration文件,它在某些情况下(networking状态,电池状态等)select不唤醒使用过多背景周期的应用程序。 例如,不正确地使用beginBackgroundTaskWithExpirationHandler,导致应用程序在后台保持活动状态,并强制iOS使其到期。 即使修复过多的背景使用也许不能解决问题,因为iOS已经确定你的应用程序是背景。 这将解释“rest所有设置”为我解决问题。

不幸的是,所有这一切都只是基于2-3天的debugging这个问题的猜测,我们可能永远不会知道,因为推送通知有太多的variables,更不用说模糊和不同的文档。