If i force close my app from background. then local notification come .And if tapped on local notification my method not called when app is running in foreground.I am newer in iOS. Please Help.
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"Reh" object:nil];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Reminder"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil,nil];
[alert show];
NSLog(#"%#",notification.soundName);
// AudioServicesPlaySystemSound (1010);
MyNotificationViewController *profile=[[MyNotificationViewController alloc]initWithNibName:#"MyNotificationViewController" bundle:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshFoeByPush" object:nil];
self.viewController = [[SWRevealViewController alloc] initWithRearViewController:self.leftMenuController frontViewController:profile]; self.viewController.rightViewController=nil;
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionCurveEaseInOut
animations:^{self.window.rootViewController = self.viewController;} completion:nil];
application.applicationIconBadgeNumber = 0;
}
else
{
NSString *tokend= [[NSUserDefaults standardUserDefaults] stringForKey:#"token"];
if (tokend == (id)[NSNull null] || tokend.length == 0 )
{
}
else
{
MyNotificationViewController *profile=[[MyNotificationViewController alloc]initWithNibName:#"MyNotificationViewController" bundle:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshFoeByPush" object:nil];
self.viewController = [[SWRevealViewController alloc] initWithRearViewController:self.leftMenuController frontViewController:profile]; self.viewController.rightViewController=nil;
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionCurveEaseInOut
animations:^{self.window.rootViewController = self.viewController;} completion:nil];
}
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification != nil) {
[self showLocalNotificationAlert:localNotification];
}
return YES;
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[self showLocalNotificationAlert:notification];
}
-(void)showLocalNotificationAlert:(UILocalNotification *)notification {
// handle here what you want
}
ALSO
When local notification fire didReceiveLocalNotification method is called not handleActionWithIdentifier
And yes put your stuff in common method -(void)showLocalNotificationAlert:(UILocalNotification *)notification so you just needs to call
When app is in forground then didReceiveLocalNotification this will called.
When app is not in forground and you tapped on notification then this notification object can be get from didFinishLaunchingWithOptions
For Remote Notification
In didFinishLaunchingWithOptions
NSDictionary *remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotification) {
[self showRemoteNotificationAlert:remoteNotification];
}
Dictionary contains payload for remotenotification
And also made common method for remote notification fire and remote notification tapped.
lol
When your app is killed and you tap on push notification this function will trigger;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
you should handle it like this,
UILocalNotification *localNotif = [launchOptionsobjectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
Parse or Do something
}
Related
My problem is, if app is in background and notification arrives and I opened the app from icon; app restores it states but I want to update the screen data in this case. Is there any way to update the data in background when notification arrives?
Here is the code which I'm using for tackling this case:
ViewController.m file code:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(appIsComingFromBackground:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
// Do any additional setup after loading the view, typically from a nib.
}
- (void) appIsComingFromBackground:(NSNotification *) note {
// code
NSString *hasMessage = [[NSUserDefaults standardUserDefaults] objectForKey:#"alertmsg"];
if([hasMessage length]!=0)
{
_labelText.text = hasMessage;
[[NSUserDefaults standardUserDefaults] setObject:#"" forKey:#"alertmsg"];
}
else{
_labelText.text = #"";
}
}
AppDelegate.m file code:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
if (application.applicationState == UIApplicationStateActive) {
}
else if(application.applicationState == UIApplicationStateBackground || application.applicationState == UIApplicationStateInactive)
{
[[NSUserDefaults standardUserDefaults] setObject:notification.alertTitle forKey:#"alertmsg"];
}
NSLog(#"Alert Message: %#", notification.alertTitle);
NSLog(#"Alert Body: %#", notification.alertBody);
}
Application is NOT Running
When the app is not running, users see notifications in the following ways, depending on the notification settings:
Displaying an alert or banner
Badging the app icon
Playing a sound
By tapping on action button of the notification, users will launch the app. In this case, the application:didFinishLaunchingWithOptions: method of the application delegate is called.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Handle launching from a notification
UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (locationNotification) {
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
return YES;
}
Applicaton is Running in Foreground
If the app is running while the notification is delivered, there is no alert displayed on screen. The application automatically calls its delegate’s application:didReceiveLocalNotification: method.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
}
// Request to reload table view data
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
Application is Running in Background
The app has been launched before but users switch to another app. When the notification is fired, users normally see an alert banner at the top of the screen. When it’s tapped, the app will be brought to the foreground. Similar to the case that the app is running in foreground, the application automatically calls its delegate’s application:didReceiveLocalNotification: method.
In Appdelegate
- (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification
{
if (application.applicationState == UIApplicationStateActive) {
}
else if(application.applicationState == UIApplicationStateBackground || application.applicationState == UIApplicationStateInactive)
{
// [[NSUserDefaults standardUserDefaults] setObject:notification.alertTitle forKey:#"alertmsg"];
[[NSNotificationCenter defaultCenter]postNotificationName:#"PushNotificationReceived" object:nil userInfo:userInfo];
}
NSLog(#"Alert Message: %#", notification.alertTitle);
NSLog(#"Alert Body: %#", notification.alertBody);
}
In view controller:
-(void)viewDidLoad
{
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(doChangesWhatdidYouWant:) name:#"PushNotificationReceived" object:nil];
}
-(void)doChangesWhatdidYouWant:(NSNotification *)notification{
//Todo
}
I use APNs to send the notifications to my app. But my app does not work well when I did the following steps:
steps
swipe the app to force quit (app is not running, not in background mode ..)
send the notification from APNs
got the notification on my iPhone and I tapped the notification banner
app seemed to try to launch(showed the launch image), but launched fail (crash?)
my app can receive notification foreground and background.
Tap the notification banner in background then it can bring app to foreground then go to the view I wrote, everything works fine.
Except force quit the APP
here is my code in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MFSideMenuContainerViewController *container = [MFSideMenuContainerViewController
containerWithCenterViewController:[self navigationController]
leftMenuViewController:leftMenuViewController
rightMenuViewController:rightMenuViewController];
self.window.rootViewController = container;
[self.window makeKeyAndVisible];
UIMutableUserNotificationAction *acceptAction =
[[UIMutableUserNotificationAction alloc] init];
// Define an ID string to be passed back to your app when you handle the action
acceptAction.identifier = #"MARK_AS_READ_IDENTIFIER";
// Localized string displayed in the action button
acceptAction.title = NSLocalizedString(#"Mark as Read", nil);
// If you need to show UI, choose foreground
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
// Destructive actions display in red
acceptAction.destructive = NO;
// Set whether the action requires the user to authenticate
acceptAction.authenticationRequired = NO;
// First create the category
UIMutableUserNotificationCategory *inviteCategory =
[[UIMutableUserNotificationCategory alloc] init];
// Identifier to include in your push payload and local notification
inviteCategory.identifier = #"actionCategory";
// Add the actions to the category and set the action context
[inviteCategory setActions:#[acceptAction]
forContext:UIUserNotificationActionContextDefault];
// Set the actions to present in a minimal context
[inviteCategory setActions:#[acceptAction]
forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObject:inviteCategory];
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert) categories:categories]];
// for calling didReceiveRemoteNotification when app first launch
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
[self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
}
return YES;
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"Device token: %#",deviceToken);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Fail to get device token: %#", error);
}
// tap the backgraund banner button
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)newUserInfo completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:#"MARK_AS_READ_IDENTIFIER"]) {
// when tapping the background banner's button will mark the notification status to read
[Functions updateComingNotificationToRead];
}
if (completionHandler) {
completionHandler();
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)newUserInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
//NSLog(#"Notification received: %# %#", newUserInfo,[newUserInfo objectForKey:#"aps"] );
userInfo = newUserInfo;
NSString *alertMessage = [[newUserInfo objectForKey:#"aps"] objectForKey:#"alert"];
UIApplicationState state = [application applicationState];
UIAlertView *alertView = nil;
// for background banner use
switch (state) {
case UIApplicationStateActive: // when app is alive, show alert to notify user
alertView = [[UIAlertView alloc]initWithTitle:NSLocalizedString(#"SmartHome",nil) message:NSLocalizedString(alertMessage,nil) delegate:self cancelButtonTitle:NSLocalizedString(#"Close",nil) otherButtonTitles:NSLocalizedString(#"Open",nil),NSLocalizedString(#"Mark as Read",nil), nil];
[alertView show];
break;
case UIApplicationStateBackground: // app is in background mode
// user tap the banner or tap the mark as read button, code will go here
[Functions addNotificationDataInDatabase:[newUserInfo objectForKey:#"uniqueID"] type:[newUserInfo objectForKey:#"deviceType"] event:[newUserInfo objectForKey:#"event"] time:[newUserInfo objectForKey:#"time"] read:#"0" description:alertMessage];
break;
case UIApplicationStateInactive: // tapping the banner
//NSLog(#"UIApplicationStateInactive");
// go to notification view
// because will go to the notification view detail, set status to read
[self gotoNotificationView:userInfo]; //uniqueID
break;
default:
break;
}
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
handler(UIBackgroundFetchResultNoData);
// send post notification for updating the badge, will get the notification in foreground
[[NSNotificationCenter defaultCenter] postNotificationName:#"APNsNotification" object:self userInfo:nil];
}
Does anyone have this problem before? Did I miss something?
Please help me!!
u can put alert and check launchOptions
if (launchOptions) {
if ([launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"]) {
[self application:self didReceiveRemoteNotification:[launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"] fetchCompletionHandler:^(UIBackgroundFetchResult result) {
}];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)newUserInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
NSString *str = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
}
}
My problem is when i am redirecting to another view controller the data is not coming. so please help me..
AppDelegate.m
i have declare like this
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSDictionary *segueDictionary = [userInfo valueForKey:#"aps"];
NSString *segueName=[[NSString alloc]initWithFormat:#"%#",[segueDictionary valueForKey:#"vendor_data"]];
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#" Offers"
message:[NSString stringWithFormat:#"%#",[[userInfo objectForKey:#"aps"] objectForKey:#"alert"]]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateInactive || [[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
MessageViewController * referObject = [[MessageViewController alloc]init];
//[self.navigationController pushViewController:referObject animated:YES];
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
[navController.visibleViewController.navigationController pushViewController:referObject animated:YES];
}
}
UIApplicationStateInactive the app is just open and it is not
redirect to MessageViewController and UIApplicationStateBackground the app is redirect to MessageViewController
I want to access the MessageViewController &
here MessageViewController is a Xib
Please help me....
Thanks
For iOS 8.x use
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler {
}
For iOS 9+ use
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler {
}
I'm developing an iOS app for iPad. I'm using Push notifications with a service called HelpShift. I'd like to run a piece of code when the users taps the notification. It actually works when the app is active, but when it's background or inactive, it doesn't work. Here is my code:
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if ([[userInfo objectForKey:#"origin"] isEqualToString:#"helpshift"]) {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"You were answered in HelpShift"
message:#"Hello"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Show", nil];
[alertView show];
} if (state== UIApplicationStateBackground) {
UIViewController *vc = self.window.rootViewController;
[[Helpshift sharedInstance] handleNotification:userInfo withController:vc];
[self showHelpShift];
} if (state == UIApplicationStateInactive) {
UIViewController *viewController =
[[UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:NULL] instantiateViewControllerWithIdentifier:#"home"];
[[Helpshift sharedInstance] handleNotification:userInfo withController:viewController];
}
}
}
- (void) showHelpShift {
UIViewController *vc = self.window.rootViewController;
[[Helpshift sharedInstance] showSupport:vc];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 1){
UIViewController *vc = self.window.rootViewController;
[[Helpshift sharedInstance] showSupport:vc];}
}
So as you can see, the problem is that the [self showHelpShift] doesn't get called or it gets called to early.
Implement application:didFinishLaunchingWithOptions: and look for the UIApplicationLaunchOptionsRemoteNotificationKey key in the launchOptions dictionary.
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Works in all cases except, when the App was running in the background and then launched by the user clicking on the notification, the app starts, the notification is shown with, but the clear doesn't work!
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *notificationPayload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(notificationPayload) {
[self application:application didReceiveRemoteNotification:notificationPayload];
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if([[userInfo valueForKey:#"aps"] valueForKey:#"alert"] != nil) {
NSString *message = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
if(message != nil) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Usage Alert"
message:message delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alertView show];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
}
}