I am doing project in that push notification is the one of the key feature.It is working fine when i am in the app,I received notification and handle that notification.
But the issue is when my app is inactive state or else remove the instance of the app.In this scenario i have received the notification didReceiveRemoteNotification method is not called, and i didn't handle the push notification.
When the App is inactive and a push notification comes through the
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
method gets called when the app is resumed and the launchOptions dictionary has the push notification, which you can get with
launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]
then you can process it as normal.
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.
if I understand correctly, the UIApplicationLaunchOptionsRemoteNotificationKey key is used on the -[UIApplicationDelegate application:didFinishLaunchingWithOptions:] method when
- the push was received when the application was not running (e.g. killed)
- the user clicked on the received push
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo) {
// app was not running and the user clicked on the push
}
}
but .. in this exact same case, the -[AppDelegate application:didReceiveRemoteNotification:fetchCompletionHandler:] is also called just after the previous one.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
// called when
// app was not running and the user clicked on the push
// app was running in background and user clicked on a push
// app was running in background and a silent push was received
// app is in foreground and a push is received
completionHandler(UIBackgroundFetchResultNewData);
}
So the question is, why should I use the UIApplicationLaunchOptionsRemoteNotificationKey if everything can be handled in the application:didReceiveRemoteNotification:fetchCompletionHandler delegate? Did I miss something?
cheers,
Jan
In case when the app is killed and user taps on push notification in notification center, launchingOptions dictionary contains UIApplicationLaunchOptionsRemoteNotificationKey so that you can adjust your app start logic.
In prior iOS version there wasn't application:didReceiveRemoteNotification: fetchCompletionHandler: and launchingOptions dictionary from application:didFinishLaunchingWithOptions: was the only place where you could handle remote notification on app start.
My guess is that application:didFinishLaunchingWithOptions: contains UIApplicationLaunchOptionsRemoteNotificationKey for compatibility reasons.
The presence of this key indicates that a remote notification is available for the app to process. The value of this key is an NSDictionary containing the payload of the remote notification.
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.
I have received push notification, if i open the push notification then didReceiveRemoteNotification is calling and i am getting the notification information, instead of if i clear the notifications and open the app then didReceiveRemoteNotification is not getting called. How to resolve this?
If you open the app from the launch icon (instead of opening it from the push notification), didReceiveRemoteNotification will not be called and you'll have no way to access the notification data. It doesn't matter if you clear the notifications or not.
If the action button is tapped (on a device running iOS), the system launches the application and the application calls its delegate’s application:didFinishLaunchingWithOptions: method (if implemented); it passes in the notification payload (for remote notifications) or the local-notification object (for local notifications).
If the application icon is tapped on a device running iOS, the application calls the same method, but furnishes no information about the notification.
As Eran pointed out, if You're opening the app from the Icon that callback will not be called. I don't know if the notification is totally removed when You delete it from the notification center list, but if the app is not running and has been launched by tapping on the notification, you can check for the notification in the launchOptions at the startup:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
*)launchOptions {
NSDictionary *notif = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if (notif) {
//handle your notification here
}
return YES;
}
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]