iOS UIBackgroundMode remote-notification doesn't work on 4G
Asked Answered
V

3

10

I'm testing push notifications with content-available=1, and they don't seem to be delivered to the app in the background unless on Wi-Fi.

I have a simple log statement at the beginning of the push notification handler:

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

    NSLog(@"Notification received: %@", userInfo);
    completionHandler(UIBackgroundFetchResultNewData);
}

Here is my test:

  1. Run the app, then press the home button to put the app in the background.
  2. Send a push notification with content-available=1
  3. Watch console logs

On Wi-Fi, the console log shows the notification. If I go to Settings and turn off Wi-Fi, switching to 4G, notifications no longer appear in the log (although they do slide in at the top of the screen, so I know they are being delivered).

There are no crash logs, and the notification is logged if I manually tap on it. Furthermore, this problem does NOT occur if I am debugging the app in Xcode. (i.e., if I am debugging in Xcode, the app will receive the notification in the background on 4G). Has anyone else experienced this behavior? Or am I doing something wrong?

EDIT: To be specific: according to my tests, if the following conditions are true, then the remote notification delegate method above will not be called:

  1. App is running in the background
  2. Phone is on LTE network, not connected to Wi-Fi
  3. App is NOT running in the Xcode debugger
  4. Notification with content-available=1 is received by the phone

However if condition 2 is removed (i.e., the phone is connected to Wi-Fi), then the handler will be called.

Veiled answered 24/7, 2014 at 8:24 Comment(5)
After turning off wifi in settings can you try going back into your app and pressing the home button again. Then send your remote notification. What happens?Rhythmical
The same result happens - I don't get the notification :( I have tried a variety of scenarios, but can never seem to receive the notification in the background on LTE. I can always receive it on Wi-Fi.Veiled
What do you do in your didReceiveRemoteNotification: fetchCompletionHandler: method? Are you taking more than 30 seconds in this method? Are you returning a correct value to the completion handler. Is it perhaps a problem with your LTE carrier's network? I have tested successfully in the background although I needed a phone restart for it to work reliablyRhythmical
I edited the question to be more clear about what's happening in the callback method and what the test conditions are. When you tested successfully, was the app running in the Xcode debugger? I have tested on multiple phones in multiple locations.Veiled
With that information I can now confirm what you are seeing - I was running under the debugger and it was working. I changed my code to call a URL on my web server that created a log file entry and ran while not connected to the debugger. With WiFi enabled the notification is displayed and a log entry is created. With WiFi disabled the notification is displayed but no log entry is created. Looks like you should log a bug with AppleRhythmical
V
1

Based on feedback from a commenter here and repeated testing on multiple devices, this appears to be a bug (or intended behavior) on iOS.

Veiled answered 6/8, 2014 at 21:47 Comment(0)
A
4

Try the following code:

// 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);

}
Auditory answered 1/8, 2014 at 7:20 Comment(2)
There is not a problem with my APNS setup.. I can receive notifications just fine. The only time something unexpected happens is when I try to receive the notification in the background on 4GVeiled
Actually what happens in this process explain in brief.Auditory
V
1

Based on feedback from a commenter here and repeated testing on multiple devices, this appears to be a bug (or intended behavior) on iOS.

Veiled answered 6/8, 2014 at 21:47 Comment(0)
M
0

For me, it worked on Wi-Fi and on 4G (LTE forced off in cellular settings), but did not work on LTE.

Update: After extensive debugging, I've found this issue related to two things for me when on LTE. One is power. I discovered if the iPhone was plugged into the wall, the app was woken up as expected. If it wasn't plugged in, the app was not woken up in response to content-available = 1. Second, was device settings. Even though every related setting was set correctly, doing a 'Reset all Settings' fixed the issue for me.

Assuming this is not an Apple bug, my guess is as iOS develops a power profile for a given app identifier, it opts, under certain circumstances (network status, battery status, etc) to not wake up apps that use excessive background cycles. For example, using beginBackgroundTaskWithExpirationHandler incorrectly, causing an app to stay active in the background and forcing iOS to expire it. Even fixing excessive background usage might not correct the issue, as iOS has already determined your app is a background hog. This would explain the 'Rest all Settings' clearing up the issue for me.

Unfortunately, all of this is just a guess based on 2-3 days of debugging this issue and we will probably never know for sure as there are so many variables in play with push notifications, not to mention vague and varying documentation.

Masha answered 21/11, 2014 at 21:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.