right now I'm developing an app capable of receiving notifications, and it was going fine, until I stepped on the need of having to send to my server a copy of the notification received on the app.
Although I know the downsides to this approach, it's the only way that I can process the notifications received.
Right now I can handle the notifications that are received with the app on background and foreground through this method
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
. Inside this method I call the NSURLConnection sendAsynchronousRequest to send to my server the notification data received.
But when the app is killed (eliminated from the the background apps), I no longer can process the notification through this method.
Is there a method that I can call when the app is killed that allows me to make a post request to my server after I receive the notification?
I think there is no way to do this until and unless you open the App...
Related
I was wondering if there was a way to wake up an app that has been terminated by the user on ios8-9. By terminated I mean double click on the home button and swipe up.
Is it somehow possible to launch an app by sending a silent push notification so that didreceiveremotenotification gets fired and gives me some runtime ?
I have noticed that a fair share of my users terminate my app. As I rely heavily on background fetch, this a problem. My idea was to send silent push notifications to launch the app in the background and trigger background fetch.
Short Answer: No That is not possible.
Detail:
When there is any new content on server you will send Remote Notification to your application to inform about that. (A Remote Notification is really just a normal Push Notification with the content-available flag set)
When application received this Remote Notification it calls following method:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
In Documentation of this method it is clearly written:
However, the system does not automatically launch your app if the user
has force-quit it. In that situation, the user must relaunch your app
or restart the device before the system attempts to launch your app
automatically again.
Reference:
objc.io: Remote Notifications
Apple Doc about application:didReceiveRemoteNotification:fetchCompletionHandler:
I am trying to achieve silent push notification.I need to save the silent push notification data in my database in app so that I can show the unseen notification and its count to users when the users uses the app.
I am using Xcode 6.1 and targeting iOS 7 and later devices. Currently, I am using development certificates for push notification.
I have checked remote notification in the background modes of target project capabilities, also the info-list's background mode has "App downloads content in response to push notifications" in required background modes.
In my AppDelegate.m, I am able to register remote notification and also get the device token. Now when I send push notification, my delegate method gets called when app is in foreground but when app is in background/not running, it doesn't get called though I receive the push notification in banner.
I have implemented this method in AppDelegate.m
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
NSLog(#"Received push notification");
}
The payload I am sending looks like this:
{
aps: {
content-available: 1
}
}
I tried adding priority, sound etc. But nothing helped me.
Can someone help me to figure out how to save silent push notification data in app when app is in running in the background or not running?
Kindly help me to resolve this issue.
So, you should definitely be able to receive them in the background, but be warned that if the user deliberately kills your app from the task switcher then it won't get them anymore.
With iOS 7 and above the callback is as you say, but before that it was
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
Seems unlikely you are targeting iOS 6 though so I would go with either a malformed push packet or background push settings not being quite right.
Do you have the apps info.plistUIBackgroundModes set to remote-notificiton?
Then also add this method to help you debug
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
//Success
handler(UIBackgroundFetchResultNewData);
}
Silent push notifications are different than user-facing notifications. They are treated as low priority and are rate limited by both APNS and iOS. In practice, this means that silent notifications can only be sent infrequently and there may be a very long delay before they are delivered to an application.
The behavior you are describing is likely the wakeup rate limiter on the device. iOS limits how often apps are launched to perform background work. This is to prevent abusive behavior - some apps might want to stay alive in the background draining the battery forever.
The wakeup rate limiter is not active when Xcode is attached, which makes silent notifications appear to be delivered instantly.
My iOS Notifications book has a lengthy chapter describing the rate limiters and how to work with them.
i have a question. I have configured my app for development push notifications and all was working fine.
All push notifications arrived the app on the device. But i want to handle the push notification in a special way. If my app is running or in background the function
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
will work fine. But is the app killed the function doesn't work. I need a idea to handle incomming push notifications whether if the app is running, in background or killed. If a push was received the app must call a callback URL. if there any way to realize this?
for example i send the following apn string:
{"aps":{"content-available":1,"alert":"This","badge":1},"callback":"https://www.xxxxxxxxx.com/sf/daniel_push/985270815/12323453534534/?device(id)=1111111111&s="}
At the end all what i want is to call the callback url if the app becomes a push notification.
Try this in didFinishLaunching:
NSDictionary *userData = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userData) {
// handle notification
}
Four questions about Push Notifications.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
//app is in foreground I can fetch
} else {
//App is in background, can I still fetch the server? Is there a time limit?
}
}
Using the code above, when the app is in background, can I still fetch the server? Is there a time limit? If the answer is: No, I cannot fetch the server in the background, are there alternatives?
Is there any other benefit of using silent notification besides triggering some method to run within 30 seconds when the app is in the background?
If using silent notification and the app is in the foreground, is the following method still called?
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
completionHandler(UIBackgroundFetchResultNewData);
}
In the payload does "content-available" : 1 calls the method in Q3 (above)? or is there anything else that can trigger the method in Q3?
Yes you can still fetch the server when the app is in background. For many apps, the background state is just a brief stop on the way to the app being suspended.
No this is the main benefit of using silent notification see this link.
Yes application:didReceiveRemoteNotification:fetchCompletionHandler: is called regardless of app state.If app is suspended or not running, then the system wakes up or launches your app and puts it into the background running state before calling the method.
This method is intended for showing the updated content to the user.When this method is called, your app has up to 30 seconds of wall-clock time to perform the download operation and call the specified completion handler block. If the handler is not called in time, your app will be suspended.
Yes it calls application:didReceiveRemoteNotification:fetchCompletionHandler:, If you want a push notification to wake your app up in the background you need to enable the Remote Notifications capability and then implement the code to handle that remote notification (either by detecting it in the application:didFinishLaunchingWithOptions: if your app is not already running, or by implementing application:didReceiveRemoteNotification:fetchCompletionHandler: in the case your app is already running). In response to the remote notificaiton you would internally trigger your fetching code. Of course you also need to be doing registering for the remote notifications and sending the token to your server. please see this discussion
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.