I'm using parse.com as my APNs provider for a test app I'm building. I've confirmed that push notifications are working as I have been able to successfully receive alerts when the app is in the foreground. Also, I have the remote-notification value for the UIBackgroundModes key specified in my plist.
In my app, I'm wanting to send a user's current location data back to my app-specific parse.com database when a push notification is received. I don't actually care about the notification payload itself, as the notification is just a means to getting a small piece of info. The app is constantly collecting data in the background and storing it in a persistent NSDictionary.
I've put the location sending code in the application:didReceiveRemoteNotification: method. If my app is in the foreground when I receive a notification, the method gets called. If my app is in the background, the method isn't called.
Am I doing something wrong?
Is it even possible to execute an API request in application:didReceiveRemoteNotification: when the app is in the background and the user hasn't interacted with the notification?**
EDIT: The problem persists even when I use application:didReceiveRemoteNotification:fetchCompletionHandler:.
Note: My NSDictionary full of location data isn't empty. Also, I am not attempting to do any UI manipulation in the background - just trying to perform an API request.
Check the following:
Notification payload includes "content-available"
{"alert":"",
"badge":"0",
"content-available":"1",
"sound":""}
The documentation for UIApplicationDelegate -application:didReceiveRemoteNotification is pretty clear on this method:
If the app is not running when a push notification arrives, the method
launches the app and provides the appropriate information in the
launch options dictionary. The app does not call this method to handle
that push notification. Instead, your implementation of the
application:willFinishLaunchingWithOptions: or
application:didFinishLaunchingWithOptions: method needs to get the
push notification payload data and respond appropriately.
You need to handle notifications in both methods to be able to respond when your app is in the background and foreground.
you can try to use this instead of
application:didReceiveRemoteNotification
method, since you need to fetch your push in background mode, thus, this would works when the app is in background mode. However, you might need to add in custom notification or UIAlertView when app is in foreground to display your message. Hope it helps and it's not too late.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(#"Remote Notification Received: %#", userInfo);
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"message to be displayed";
notification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
completionHandler(UIBackgroundFetchResultNewData);
}
Alex L's answer almost worked for me.
Just make sure the value of content-available is 1 (number), not a string "1":
{
"alert":"",
"content-available":1,
"sound":""
}
badge parameter is optional.
(Using Parse Server for APNs)
Related
I have a problem with push notifications in iOS, in a similar scenary to this and this and another one.
Also, this post resume all possible situations.
In my case:
app is NOT RUNNING
content-available:1
UIBackgroundModes contains 'remote-notifications' and 'fetch'
If the user force-quit the app and receives a push notification, then it could open app from alert or from icon.
When the user tap on the notification the app will be opened and the following method will be executed:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Handle for notifications when app is closed
if (launchOptions) {
NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
if (apsInfo) {
// handle notification
}
}
No problem up to here, I have the payload to doing something with that info (for example to fetch new data from server).
But if the user open the app from the icon I don't have any way to handle the payload (Although didFinishLaunchingWithOptions is execute, I don't have the aps info, according to docs here).
So, the question is, there are any way to solve that?
For example, I made the test with WhatsApp, and they handle that situation, (probably they are using VOIP notifications instead of Remote Notifications)
Regards
You should never assume that state has remained consistent between the time the notification has been delivered and the time the user has launched the app. Nor, even, that it is the same device. I'll frequently get a "Hey! Do something!" notification on my phone and, if my iPad is handy, respond to it on my nice big iPad screen.
Instead, you should round trip to the server and grab the most up to date state for that user at the time of app launch or activation.
I have created an app in which background fetch code is written on receiving push notification. I have enabled the background mode in .plist, content-available key is set to 1 in push notification payload, registered for push notification and using delegate
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
Now when my app is in background, I receive a call.
During call, I receive a push notification for my app.
On receiving the push notification during a call, push notification delegate is not getting called.
So to handle the push notification/Remote Notification during phone call here below the method is:
When the phone call is received the app is become inactive and when the phone call is disconnected then the app become active and the Method "applicationDidBecomeActive" in the AppDelegate is called.Hence you can call back the Remote Notification in the didReceiveRemoteNotification method in the applicationDidBecomeActive.
Even you can handle the push notification when the app is terminated.
such as move on the specific viewController, didFinishLaunchingWithOptions contains the dictionary which contains the payload of the notification when app is terminated and Push notification is received . This can be done as . `.
if (launchOptions != nil)
{
// opened from a push notification when the app is closed
NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo != nil)
{
}
}
else
{
// opened app without a push notification.
}`
hope this will work :)
I guess during phone call cellular chip is being used for voice transmission. Data transmission is extra work for the chip to do which could affect battery life dramatically. This is a more a conscious decision by Apple to make it more of a silent notification during phone calls.
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification) {
NSLog(#"app recieved notification from remote%#",notification);
[self application:application didReceiveRemoteNotification:(NSDictionary*)notification];
}else{
NSLog(#"app did not recieve notification");
}
here I am getting app did not receive notification method why ?
It's always a good idea to consult Apple's documentation first when it comes to their SDK.
Having a look here:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/
You will see this extract:
When a remote notification arrives, the system calls the
application:didReceiveRemoteNotification:fetchCompletionHandler:
method. Notifications usually signal the availability of new
information. In your app delegate method, you might begin downloading
new data from a server so that you can update your app’s data
structures. You might also use the notification to update your user
interface.
If you're not using Push notifications, but local notifications, then you need this method: application:didReceiveLocalNotification:
The reason the method does not get executed is due to not receiving a remote notification.
I am working on a app, where I need to send a push notification to the app to start processing data as needed.
How do I send a push notification to the device so that instead of showing the alert message, the notification is forwarded to the app - whether the app is in the foreground or background..
I did implement the delegate method :
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
however this is called only when the app is in the foreground. When the app is in the background the notification shows up on the notification center.
Please advice.
To make this works you need to do few step:
set background mode remote-notification
implement application:didReceiveRemoteNotification:fetchCompletionHandler: method in app delegate
and make sure push notification payload contains key "content-available" : 1
related docs:
App States and Multitasking
Local and Push Notifications in Depth
Is your application using a backend? An example would be Parse or another to store your data.
Parse, for example, allows you to add push notifications that can be customized and changed to get the most out of your application.
I am receiving a remote push notification, and i need to register a UILocalNotification, within 30 minutes, but i need to do it even if the user do not click in the notification, in the background.
There's any way to do it, like in :
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
}
It works fine here, but only if the user clicks in the notification, or if the app is currently running.
You can't handle a remote notification if the application is not running until the user doesn't launch your app. You should deal with the business logic on server-side. Keep track of when the notifications are sent and trigger the appropriate action after the time frame are exceeded.
You need to turn on "background fetch" in the "capabilities" section of your project settings, and use the application:didReceiveRemoteNotification:fetchCompletionHandler delegate method in your ApplicationDelegate file. This way you can handle remote notifications in the background. Don't forget to set the content-available flag in your aps dictionary when sending the push.