I'm working on push notification flow but not getting exactly how to handle it. I need a simple explanation, when push notification comes, which delegate is called
When user tap on push notification label
When user tap on App icon when push notification comes
I'm unable to maintain to my app application state, for me the flow should be like:
When user tap on push notification label: It should open a particular viewcontroller
When user tap on App icon when push notification comes: It should open same viewcontroller from where app goes in background
How I can achieve this in Xcode 8.1/iOS 10.1.1?
Also I'm using background mode remote notification and background fetch.
In AppDelegate.m used it to check where user tap icon
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//Handle notification when the user click it while app is running in background or foreground.
if(application.applicationState == UIApplicationStateInactive) {
NSLog(#"Inactive - the user has tapped in the notification when app was closed or in background");
//do some tasks
}
else if (application.applicationState == UIApplicationStateBackground) {
NSLog(#"application Background - notification has arrived when app was in background");
}
else {
NSLog(#"application Active - notication has arrived while app was opened");
//do tasks
}
}
When a push notification sends from server a delegate call on app side but you have to register from app end by adding registerForPushNotifications.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//Handle notification when the user click it while app is running in background or foreground.
//Where userinfo is a dict. It has the data sent from server
}
Related
Using FCM for push notifications in iOS 10:
This is the snipper that's getting called after pushing a notification via our own API:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
[[FIRMessaging messaging] appDidReceiveMessage:userInfo];
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
completionHandler(UIBackgroundFetchResultNewData);
if(application.applicationState == UIApplicationStateBackground){
[[TWMessageBarManager sharedInstance] showMessageWithTitle:#"Bacgkround"
description:#"Wassup"
type:TWMessageBarMessageTypeSuccess callback:^{
}];
}
else if(application.applicationState == UIApplicationStateActive){
[[TWMessageBarManager sharedInstance] showMessageWithTitle:#"Active"
description:#"Wassup"
type:TWMessageBarMessageTypeSuccess callback:^{
}];
}
else if(application.applicationState == UIApplicationStateInactive){
[[TWMessageBarManager sharedInstance] showMessageWithTitle:#"InActive"
description:#"Wassup"
type:TWMessageBarMessageTypeSuccess callback:^{
}];
}
}
When the app is active, above method gets called and UIApplicationStateActive case gets executed and I am showing a pop-up using a 3rd party library. When I press the Home button and push a notification, above method gets called and UIApplicationStateBackground gets executed but I am not sure how do I show a notification in the form of a banner?
Is this the method where I have to handle the notifications? If yes, how do I handle Background and Inactive states?
you just have to put notification body in payload you receive from server, if you don't add it, iOS consider it as silent push notification and will not show notification banner.e.g
{
"data":{
"title":"mytitle",
"body":"mybody",
},
"notification":{
"title":"mytitle",
"body":"mybody",
},
}
when user clicks on notification banner in what ever state application is, you will get its call back method triggered as provided by firebase.e.g.
// [START receive_message]
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
etc.
NOTE: no need to use any third party library to show notification banners as all this is controlled by iOS.
I do not know much about TWMessageBarManager but i can tell you can not user any lib or anything you've made custom to show notification while your app is not in foreground. If your app is in background and you receive a push notification the notification banner will be shown itself by the iOS
I build and app that has Background Modes enabled, and the push notification payload that the app gets has "content-available" key.
This setup results in didReceiveRemoteNotification being called EVERY TIME the app gets a push notification, which means that if i get 3 push notifications while the app is in the background - the function will fire 3 times and the code inside it will be executed when the app will applicationDidBecomeActive
My biggest problem is that there is NO way to know if a user tapped the Push System Alert or tapped the app icon to bring the app from background, since regardless of the user's action, the didReceiveRemoteNotification will fire.
Is there a way to know for sure that the user tapped on the Sys alert?
and this: http://samwize.com/2015/08/07/how-to-handle-remote-notification-with-background-mode-enabled/
and other answers
don't seem to be helpful
For app is background push
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground )
{
//opened from a push notification when the app was on background
}
}
For app is terminate state
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
// Launched from push notification
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
}
An app is running on iPhone and user tap the home button once and app will enter background.
after 2 or 3 seconds local notification arrives and user tap on local notification.
app will again enter in foreground and become active and didReceiveLocalNotification will be called.
How to determine that app become active by tapping on local notification not the app icon.
Here is an easy way to detect what's your App's status when UILocalNotification fired and if
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
is called, this makes sure that local notification is received.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
} else {
}
}
I have checked many threads and Apple Documentation for determining whether app is launched on tap of the notification.
I want to handle push notification only if user taps on notification.
I am not able to figure out reason of application:didReceiveRemoteNotification:fetchCompletionHandler: being called.
How can check if this method was called on tap of notification or direct from push when app is background.
Thanks.
Here is few steps for push Notification
1). When you app is killed, neither active nor in background. In that case didFinishLaunchingWithOptions will called when you receive any notification.
2). When your app is active or in background, in that case didReceiveRemoteNotification:fetchCompletionHandler** will called. You have to identify application state here as below.
if ( application.applicationState == UIApplicationStateActive ) {
// app was already in the foreground
}
else {
// app was just brought from background to foreground
}
- (void)application:(UIApplication *)app didReceiveRemoteNotification:(NSDictionary *)userInfo {
//No Need to store the push notification if it is in active or in closed state we can directly navigate to the screens
NSLog(#"notification didReceive method called");
if([app applicationState] == UIApplicationStateInactive) {
//If the application state was inactive, this means the user pressed an action button
//Handle the code after push notification received
}
else if ([app applicationState] == UIApplicationStateActive) {
//Application is in Active state handle the push notification here
}
}
Is there any way to find out after notification is been sent, how many users clicked on the notification and how many people didnt click on the noficiation event (badge) when the app is in the background?
I am more interested to find out how many people didnt click, as people who clicked can be tracked as app will go in the foreground and request can be made vs if app is in the background, your http request may get lost.
update your app delegate code to the following code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[super application:application didFinishLaunchingWithOptions:launchOptions];
NSDictionary *remoteNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(remoteNotif)
{
//launched from push notification
}else{
//Did not launch from push notification (tapped on app icon, or from multi tasking)
//**Didn't click on notification**
}
}
and this:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if([application applicationState] == UIApplicationStateActive) {
// app was open, did not display the push alert/banner/badge
// **Didn't click on notification**
}else{
//launched from push notification
}
}
Its quite self explanatory. you can track when app was opened by tapping on a push notification and when it was opened without tapping on a notification.
I guess the closest you can come to know who didn't click your notification is by checking in your AppDelegate's didFinishLaunchWithOptions method that your app didn't get launched as a result of the user tapping a notification after you send out the notification. In other words, I think you answered your own question in your question.