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.
Related
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 {
}
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
}
Currently I'm working on handling push notification and I get bug when the first notification success received and shows me the destination view controller. But for the second and the rest the application crash. I get the problem is the app doesn't receive the parameter that should get from push notification.
AppDelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//[PFPush handlePush:userInfo];
NSLog(#"didReceiveRemoteNotification userInfo=%#", userInfo);
if(application.applicationState == UIApplicationStateActive)
{
NSDictionary *aps = userInfo[#"aps"];
NSString *alertTitle = #"";
if([userInfo[#"page"] isEqualToString:#"ga"])
{
alertTitle = #"General Advisory";
}
else if ([userInfo[#"page"] isEqualToString:#"cr"])
{
alertTitle = #"Customer Recommendation";
}
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:alertTitle
message:[aps objectForKey:#"alert"]
delegate:self
cancelButtonTitle:#"Close"
otherButtonTitles:nil];
[alert addButtonWithTitle:#"View"];
//set tag to id
alert.tag = [userInfo[#"id"] intValue];
[alert show];
}
else if(application.applicationState == UIApplicationStateInactive)
{
[self movePageAfterReceiveNotification:userInfo[#"page"] withId:userInfo[#"id"]];
}
}
- (void)movePageAfterReceiveNotification:(NSString *)page withId:(NSString *)pageId
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
UITabBarController *tabBarVC = (UITabBarController*)topController.presentedViewController;
if (tabBarVC.selectedIndex > 0)
{
[tabBarVC setSelectedIndex:0];
}
UINavigationController *navcon = (UINavigationController*)[tabBarVC.viewControllers firstObject];
HomeViewController *homeVC = (HomeViewController*)[navcon topViewController];
NSLog(#"Page: %#",page);
NSLog(#"ID: %#",pageId);
if ([page isEqualToString:#"ga"])
{
//redirect to homeVC
[homeVC loadDataGeneralAdvisoryFromPushNotif:pageId];
}
else if ([page isEqualToString:#"cr"])
{
//redirect to homeVC
[homeVC loadDataCustomerRecommendationFromPushNotif:pageId];
}
}
The error like this:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CRDetailViewController loadDataCustomerRecommendationFromPushNotif:]: unrecognized selector sent to instance 0x14756d180'
The topViewController of your first navigation controller (tab one) is not HomeViewControlled but CRDetailViewController. As you can see the error message says '-[CRDetailViewController loadDataCustomerRecommendationFromPushNotif:]: unrecognized selector sent to instance 0x14756d180'
You probably want your HomeViewController to handle that information, because that view controller is the one implementing your loadDataCustomerRecommendationFromPushNotif method.
I guess you should call [navcon popToRootViewControllerAnimated:NO] right before HomeViewController *homeVC = (HomeViewController*)[navcon topViewController];
Something like this, probably:
UINavigationController *navcon = (UINavigationController*)[tabBarVC.viewControllers firstObject];
[navcon popToRootViewControllerAnimated:NO]
HomeViewController *homeVC = (HomeViewController*)[navcon topViewController];
I'm having my head cracking just to figure out the code error in this problem .
My error : Use of undeclared identifier 'alertView'
appdelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate,UIAlertViewDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
appdelegate.m
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Daily Vibes"
message:notification.alertBody
delegate:self cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Okay"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MyViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MyViewController"];
[(UINavigationController*)self.window.rootViewController pushViewController:vc animated:NO];
}
}
You missed a close bracket for this method
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Daily Vibes"
message:notification.alertBody
delegate:self cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
}
} // <<<<----------- Here
[[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];
}
}
}