Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

didReceiveRemoteNotification:fetchCompletionHandler not being called when app is in background and not connected to Xcode

I've a very strange problem, I implemented:

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

For silent remote push notification. It works perfect when app is in background and connected to Xcode. When I unplug any iOS device and run the app, move to background and send remote notification, didReceiveRemoteNotification:fetchCompletionHandler not being called.

My code below:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {     NSInteger pushCode = [userInfo[@"pushCode"] integerValue];     NSLog(@"Silent Push Code Notification: %i", pushCode);     NSDictionary *aps = userInfo[@"aps"];     NSString *alertMessage = aps[@"alert"];      if (pushCode == kPushCodeShowText) {         UILocalNotification *localNotif = [[UILocalNotification alloc] init];         localNotif.fireDate = [NSDate date];         localNotif.timeZone = [NSTimeZone defaultTimeZone];         localNotif.alertBody = alertMessage;         localNotif.alertAction = @"OK";         localNotif.soundName = @"sonar.aiff";         // localNotif.applicationIconBadgeNumber = 0;         localNotif.userInfo = nil;         [[UIApplication sharedApplication] presentLocalNotificationNow:localNotif];          UILocalNotification *clearNotification = [[UILocalNotification alloc] init];         clearNotification.fireDate = [NSDate date];         clearNotification.timeZone = [NSTimeZone defaultTimeZone];         clearNotification.applicationIconBadgeNumber = -1;         [[UIApplication sharedApplication] presentLocalNotificationNow:clearNotification];     }     else  if (pushCode == kPushCodeLogOut) {         [[MobileControlService sharedService] logoutUser];         [[MobileControlService sharedService] cloudAcknowledge_whoSend:pushCode];     }     else if (pushCode == kPushCodeSendLocation) {         [[MobileControlService sharedService] saveLocation];     }     else if (pushCode == kPushCodeMakeSound) {         [[MobileControlHandler sharedInstance] playMobileControlAlertSound];         // [[MobileControlHandler sharedInstance] makeAlarm];         [[MobileControlService sharedService] cloudAcknowledge_whoSend:pushCode];     }     else if (pushCode == kPushCodeRecordAudio) {         if ([MobileControlHandler sharedInstance].isRecordingNow) {             [[MobileControlHandler sharedInstance] stopRecord];         } else {             [[MobileControlHandler sharedInstance] startRecord];         }         [[MobileControlService sharedService] cloudAcknowledge_whoSend:pushCode];     }     completionHandler(UIBackgroundFetchResultNewData); }  - (void)saveLocation {     bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{         [[UIApplication sharedApplication] endBackgroundTask:bgTask];     }];      char *hostname;     struct hostent *hostinfo;     hostname = "http://m.google.com";     hostinfo = gethostbyname(hostname);     if (hostname == NULL) {         NSLog(@"No internet connection (saveLocation)");         return;     }      if (self.locationManager.location.coordinate.latitude == 0.0 || self.locationManager.location.coordinate.longitude == 0.0) {         NSLog(@"saveLocation - coordinates are 0.0.");         return;     }      NSLog(@"saveLocation - trying to get location.");     NSString *postBody = [NSString stringWithFormat:@"Lat=%@&Lon=%@&Date=%@&userID=%@&batteryLevel=%@&version=%@&accuracy=%@&address=%@", self.myInfo.lat, self.myInfo.lon, self.myInfo.date, self.myInfo.userID, self.myInfo.batteryLevel, self.myInfo.version, self.myInfo.accuracy, self.myInfo.address];  NSURL *completeURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/saveLocation", WEB_SERVICES_URL]]; NSData *body = [postBody dataUsingEncoding:NSUTF8StringEncoding]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:completeURL]; [request setHTTPMethod:@"POST"]; [request setValue:kAPP_PASSWORD_VALUE forHTTPHeaderField:kAPP_PASSWORD_KEY]; [request setHTTPBody:body]; [request setValue:[NSString stringWithFormat:@"%d", body.length] forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];   if (__iOS_7_And_Heigher) {     NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];     NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];     NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {         if (error) {             NSLog(@"saveLocation Error: %@", error.localizedDescription);         } else {             NSString *responseXML = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];             NSLog(@"\n\nResponseXML(saveLocation):\n%@", responseXML);             [self cloudAcknowledge_whoSend:kPushCodeSendLocation];         }     }];     [dataTask resume]; } else {     [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {         if (connectionError) {             NSLog(@"saveLocation Error: %@", connectionError.localizedDescription);         } else {             NSString *responseXML = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];             NSLog(@"\n\nResponseXML(saveLocation):\n%@", responseXML);             [self cloudAcknowledge_whoSend:kPushCodeSendLocation];         }     }]; } }  - (void)startBackgroundTask {     bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{         [[UIApplication sharedApplication] endBackgroundTask:bgTask];     }]; }  - (void)endBackgroundTask {     if (bgTask != UIBackgroundTaskInvalid) {         [[UIApplication sharedApplication] endBackgroundTask:bgTask];         bgTask = UIBackgroundTaskInvalid;     } } 

And [self endBackgroundTask] is at the end of cloudAcknowledge function. Any idea what the hell is going on here?

EDIT:

Payload goes like this: { aps = { "content-available" = 1; }; pushCode = 12; }

like image 708
Idan Moshe Avatar asked Dec 23 '13 10:12

Idan Moshe


People also ask

Do push notifications work when app is closed iOS?

Apple does not offer a way to handle a notification that arrives when your app is closed (i.e. when the user has fully quit the application or the OS had decided to kill it while it is in the background). If this happens, the only way to handle the notification is to wait until it is opened by the user.

Do push notifications work when app is closed?

One of the major features of web apps (both on desktop and mobile browsers) is the ability to send push notifications that are delivered even when the website is closed.

How do I enable push notifications in Swiftui?

Add a new capability by clicking on + Capability. Add Push Notifications and Background Modes to your project. Under Background Modes, check Background fetch and Remote notifications. This will allow us to send notifications from our server (Firebase Cloud Messaging) to the user.

How do I send a Swiftui notification?

If you run your app now, press the first button to request notification permission, then press the second to add an actual notification. Now for the important part: once your notification has been added press Cmd+L in the simulator to lock the screen.


1 Answers

There could be number of things might have gone wrong, The first from my own experience. In order to make silent push notification work. Your payload has to be structured correctly,

{     "aps" : {         "content-available" : 1     },     "data-id" : 345 } 

Does your push message has content-available: 1 if not then iOS will not call the new delegate method.

- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 
like image 110
TeaCupApp Avatar answered Sep 20 '22 10:09

TeaCupApp