I have already
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateActive )
// app was already in the foreground
else
// app was just brought from background to foreground
...
}
Now is that possible that I perform some some set of action when notification arrive, keeping the application in background; I don't want to bring my app at foreground when notification is received; What I want is when notifications arrive, I just set some flags and (app is still in background) and when user open the app himself, he/she can view the message in some graceful way;
Summary: I don't want to bring the application in foreground when notifications arrives, but want to perform some actions in my code keeping the app in background;
Thanks;
You will want to use
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
Since your app is in the background it won't know anything about the incoming notifications. The notification is taken care of by iOS.
However, when your app opens due to a user swiping/tapping the notifications your app will get the launchOptions passed in the above method. If the user opens the app directly (tapping the app icon) the launchOptions will be empty. See the UIApplicationDelegate Protocol Reference for more details.
To retrieve remote notification payload you can do:
[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
for the local notification payload you can do:
[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]
Related
I want to understand what will happen if a push notification arrives to device.
App Not running - what will happen if notification arrives - state change?
App is in foreground - ?
App is background - ?
App is inactive state ?
I am assuming if App is not running we can invoke by sending a silent push notification in some situations.
Can some one explain me how a push notification works based on app state.
If the application is not running or in background state, if the user accepted to receive push notifications, the push notification will be sent to the device that will display it on screen.
From this displayed notification, you can launch or wake the target application.
The traditional launch callback:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
will be fired and you can access the received notification and its payload from its launchOptions dictionary, using UIApplicationLaunchOptionsRemoteNotificationKey key.
If the application is running and in foreground, the AppDelegate method
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary *)userInfo
will be fired, userInfo containing the push notification payload.
I have a scenario in which app will get push notification and need to show that messages in home screen of my app, for that i saved the message array into user defaults from my app delegate and everything works well, but in following conditions it's not working
if app is in killed state and a notification came and user triggeres the app through the app icon (not from push notification )
if app is in background and notification came and user enters to app through app icon (not from push message ) in this case also
Then i searched for solutions and came to know about silent push notifications (for background mode) and nothing else so i need to know how to handle all scenarios by push notifications and my appdelegete is
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDictionary *remoteNotif = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif) {
[self handlePushMessage:remoteNotif];
}
return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self handlePushMessage:userInfo];
}
-(void)handlePushMessage :(NSDictionary*)userInfo{
//method to handle push message
}
Thanks in advance
This is a common issue: if the user does not open your app by means of the displayed notification, there is no* way of getting the related information.
* A possible solution employed by many apps is to check with a remote server for unread notifications (e.g. check for an unset read-date field).
In scenario 1. NSDictionary *remoteNotif = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey]; here remoteNotif return nil as you enter into the app through triggering app icon.
In scenario 2. You can get push notification info through the following method
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if (userInfo) {
[self handlePushMessage:userInfo];
}
}
if app is in killed state and a notification came and user triggeres the app through the app icon (not from push notification )
If the app is in killed state then the push notification payload can only be handed over to the app when the user taps the push notification itself. If the user launches the app from app icon then the notification payload will not be passed to the application
if app is in background and notification came and user enters to app through app icon (not from push message ) in this case also
if you are targeting iOS7 and up then you need to enable background mode for remote notifications. Please check below link in order to get notification payload even when app is in background
didReceiveRemoteNotification not working in the background
The above mentioned app delegate method gets called when the app is in foreground,Background and suspended state.
There is no way to get the notification payload when app is killed and when the app icon is directly clicked instead of push notification in notification center.
Enable "Remote Notifications" under background modes in capabilities in target settings. This will fetch the notification data even when the app is in the background. Also, make sure to implement:
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler;
in your app delegate.
When my app is on background and I receive a remote notification, two things can happen:
I tap on the push notification banner, my apps comes to foreground and didReceiveRemoteNotification is called.
I tap on my app icon from the springboard, my app comes to foreground and didReceiveRemoteNotification IS NOT called.
So, in the scenario 1, I can update my counter of unread messages inside the app in response to didReceiveRemoteNotification.
In the scenario 2, I can't.
How can I solve this using Quickblox?
As one possible variant:
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo) {
[self handleRemoteNotifications:userInfo];
}
// Override point for customization after application launch.
return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[self handleRemoteNotifications:userInfo];
}
#pragma mark - Remote notifications handling
-(void)handleRemoteNotifications:(NSDictionary *)userInfo {
// do your stuff
}
#end
When app is not running, in didFinishLaunchingWithOptions: you can use this code for get push's payload:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSString *myKey = [userInfo objectForKey:#"myKeyFromPayload"];
}
Remember to set permission in plist
For the remote push you can use in your appdelegate:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
The issue is probably that application:didReceiveRemoteNotification: is not called if the app is not running. To quote Apple documentation:
This document is outdated
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.
This is the new document
Use this method to process incoming remote notifications for your app. Unlike the application:didReceiveRemoteNotification: method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives. 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.
You have to enable Remote Notifications in the Background Modes.
To do so, automatically: (Xcode5)
- Go to your Project settings -> Capabilities -> Background Modes
- Tick "Remote Notifications"
To do so, manually:
- Open your %appname%-Info.plist
- Right click and tick "Show Raw Keys/Values"
- Right click and choose "Add Row"
- Type in "UIBackgroundModes" (Key)
- The key will be created, and the type is an Array
- Add new item in the array with the value of "remote-notification" (Value) and press enter
- Now you have 1 item in your array called: "Item 0", if you had any other items in there, just add this item (remote-notification) to the array.
Be sure to use these methods frankWhite used :)
Hope this helps ;)
I'm setting up Apple push notification for my iOS app.
If several notification are received when the app is not running (or in background), how can all received notifications be taken into account when the app (re)starts ?
In iOS 5 the push notifications accumulate in the tray.
In application:didFinishLaunchingWithOptions:
use UIApplicationLaunchOptionsRemoteNotificationKey. This will give you the notification dictionary.
May be this can help you -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
There is no way of getting push notifications programmatically.
The only way to handle these notifications is to implement application:didFinishLaunchingWithOptions: which will contain data about the notification that the user tapped.
The good way to achieve what you want is to have a web service of your own that you call when your application enters foreground.
I have something fairly simple I want to do. I attach a custom piece of data to some push notifications that I handle in
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
I look for the UIApplicationLaunchOptionsRemoteNotificationKey and hey presto there it is.
That method only gets called if my app is being launched for the first time. How do I read that same key if my application is running in the background already when the notification comes in and the user pressed the 'View' button on the notification? I want to send them to a particular view controller with that data open on it, the same as I do if the app is being launched for the first time from the notification.
Check out application:didReceiveRemoteNotification:fetchCompletionHandler: in iOS 7 and later.
The method application:didReceiveRemoteNotification: is called if your app is running in the foreground. It also is called if your app is running in the background and the user engages with your push notification (thus making your app active).
So, the real question is how to determine if the app was in the foreground or if it was made active by the user engaging with your push notification.
It looks like this answer to the question didReceiveRemoteNotification when in background has the key:
You can tell whether your app was just brought to the foreground or not in application:didReceiveRemoteNotification: using this bit of code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateActive )
// app was already in the foreground
else
// app was just brought from background to foreground
...
}
To detect if the app was activated by remote notication, try this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo == NULL)
{
NSLog(#"didFinishLaunchingWithOptions user startup userinfo: %#", userInfo);
}
else
{
NSLog(#"didFinishLaunchingWithOptions notification startup userinfo: %#", userInfo);
}
}