IOS: handleActionWithIdentifier event not fired on real device - ios

I am using UILocalNitification to send notifications when the app is running in the background, my code is:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
// ask fo permission to send alert
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge categories:nil]];
}
UIMutableUserNotificationAction *acceptAction =
[[UIMutableUserNotificationAction alloc] init];
// Define an ID string to be passed back to your app when you handle the action
acceptAction.identifier = #"ACCEPT_IDENTIFIER";
// Localized string displayed in the action button
acceptAction.title = #"Take Photos";
// 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 = #"PHOTO";
// 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 setWithObjects:inviteCategory, nil];
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
[self.window makeKeyAndVisible];
return YES;
}
and the code use to handle the button event is:
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler{
if ([identifier isEqualToString:#"ACCEPT_IDENTIFIER"]) {
NSLog(#"Here");
}
completionHandler();
}
My problem is when testing on a simulator, the button event can be captured, but when testing on a real device (iPod with iOS version 8.1.2 and iPhone 5S iOS8.1.X), both devices cannot get the button event.
Can anybody help?

Related

Why remote notification action is doing nothing after clicking?

I have configured an action for a remote notification when it arrives to my iOs app. I want two different actions whether one key passed in the payload. The code seems to be executed, but the app doesn't open, nor the safari url. Here is my AppDelegate.m:
NSString *const NotificationCategoryOpenView = #"openView";
NSString *const NotificationActionOpenView = #"View";
- (void)registerForNotification {
UIApplication *application = [UIApplication sharedApplication];
// iOs 8 or greater:
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIMutableUserNotificationAction *open;
open = [[UIMutableUserNotificationAction alloc] init];
[open setActivationMode:UIUserNotificationActivationModeBackground];
[open setTitle:NSLocalizedString(#"View", nil)];
[open setIdentifier:NotificationActionOpenView];
[open setDestructive:NO];
[open setAuthenticationRequired:NO];
UIMutableUserNotificationCategory *actionCategory;
actionCategory = [[UIMutableUserNotificationCategory alloc] init];
[actionCategory setIdentifier:NotificationCategoryOpenView];
[actionCategory setActions:#[open]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObject:actionCategory];
UIUserNotificationType types = (UIUserNotificationTypeAlert|
UIUserNotificationTypeSound|
UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings;
settings = [UIUserNotificationSettings settingsForTypes:types
categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else if ([application respondsToSelector:#selector(registerForRemoteNotificationTypes:)]) {
// iOs 7 or lesser:
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:NotificationActionOpenView]) {
NSDictionary *aps = userInfo[#"aps"];
if ([[aps allKeys] containsObject:#"viewToOpen"]){
NSString *webString = [[NSString alloc] initWithFormat:#"%#", aps[#"viewToOpen"]];
NSURL *webURL = [[NSURL alloc] initWithString:webString];
// This line doesn't work:
[[UIApplication sharedApplication] openURL:webURL];
} else {
// These two lines doesn't work:
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController popToRootViewControllerAnimated:NO];
}
}
completionHandler();
}
Thanks!
Your code should be in this method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if(userInfo) {
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
NSUInteger notificationType = [[userInfo valueForKey:API_NOTIFICATION_TYPE] integerValue];
if (state == UIApplicationStateActive) {
// Write code which should work when notification comes and app is active
}
else {
// Write code which should work when notification comes and app is in background or inactive or terminated
}
}
}
}
This method will get called only
when app is ACTIVE and notification comes
when app is in background or inactive or terminated and notifications comes and user taps on it
Implement
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler
And
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
Methods.
Notification activation mode is set to UIUserNotificationActivationModeBackground,which Activate the app and put it in the background. If the app is already in the foreground, it remains in the foreground.So if you want to application in foreground/launch then use UIUserNotificationActivationModeForeground
[open setActivationMode:UIUserNotificationActivationModeBackground];
Use this activation option:
[open setActivationMode: UIUserNotificationActivationModeForeground];
Check weather webUrl is proper and working as expected in normal flow.
For Xcode 8, u will have to migrate push notification using UserNotification framework.

Apple Push Notification (remote) is not working when the screen is locked. Nothing is shown on Apple's notification tab too

When I push the notification, iPhone screen turns on (probably because the app is awaken.) However no notification is shown on lock screen or notification tab.
iOS notification is not working when screen is locked. Nothing is shown in Notification tab too. Banner is working fine when app is in background (screen unlocked) or foreground.
I use the following code to push notification using node-apn (I opened a ticket on the repo too: https://github.com/argon/node-apn/issues/418):
function pushNotificationToMany() {
console.log("Sending the same notification each of the devices with one call to pushNotification.");
var note = new apn.notification();
note.setAlertTitle("Hello from my app");
note.setAlertText("Hello, world!");
note.setCategory("message");
note.setContentAvailable(1);
note.badge = 1;
service.pushNotification(note, tokens);
}
pushNotificationToMany();
My iOS code in AppDelegate.m include the following functions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSLog(#"Registering for push notifications...");
UIMutableUserNotificationCategory* notificationCategory = [[UIMutableUserNotificationCategory alloc] init];
notificationCategory.identifier = #"message";
NSSet *categories = [NSSet setWithObjects:notificationCategory, nil];
[[UIApplication sharedApplication] registerForRemoteNotifications];
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:categories]];
NSDictionary *payload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (payload)
NSLog(#"payload is : %#", payload);
return YES;
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings // NS_AVAILABLE_IOS(8_0);
{
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
NSLog(#"deviceToken: %#", deviceToken);
NSString * token = [NSString stringWithFormat:#"%#", deviceToken];
//Format token as you need:
token = [token stringByReplacingOccurrencesOfString:#" " withString:#""];
token = [token stringByReplacingOccurrencesOfString:#">" withString:#""];
token = [token stringByReplacingOccurrencesOfString:#"<" withString:#""];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"remote notification user info %#", userInfo);
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler {
NSLog(#"another remote notification user info %#", userInfo);
if(application.applicationState == UIApplicationStateInactive) {
NSLog(#"Inactive");
//Show the view with the content of the push
handler(UIBackgroundFetchResultNewData);
} else if (application.applicationState == UIApplicationStateBackground) {
NSLog(#"Background");
//Refresh the local model
handler(UIBackgroundFetchResultNewData);
} else {
NSLog(#"Active");
//Show an in-app banner
handler(UIBackgroundFetchResultNewData);
}
}
Looks like I need to add in UIMutableUserNotificationAction in order to get the results I want. The following code works:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSLog(#"Registering for push notifications...");
UIMutableUserNotificationAction *notificationAction1 = [[UIMutableUserNotificationAction alloc] init];
notificationAction1.identifier = #"Accept";
notificationAction1.title = #"Accept";
notificationAction1.activationMode = UIUserNotificationActivationModeBackground;
notificationAction1.destructive = NO;
notificationAction1.authenticationRequired = NO;
UIMutableUserNotificationAction *notificationAction2 = [[UIMutableUserNotificationAction alloc] init];
notificationAction2.identifier = #"Reject";
notificationAction2.title = #"Reject";
notificationAction2.activationMode = UIUserNotificationActivationModeBackground;
notificationAction2.destructive = YES;
notificationAction2.authenticationRequired = YES;
UIMutableUserNotificationAction *notificationAction3 = [[UIMutableUserNotificationAction alloc] init];
notificationAction3.identifier = #"Reply";
notificationAction3.title = #"Reply";
notificationAction3.activationMode = UIUserNotificationActivationModeForeground;
notificationAction3.destructive = NO;
notificationAction3.authenticationRequired = YES;
UIMutableUserNotificationCategory *notificationCategory = [[UIMutableUserNotificationCategory alloc] init];
notificationCategory.identifier = #"Email";
[notificationCategory setActions:#[notificationAction1,notificationAction2,notificationAction3] forContext:UIUserNotificationActionContextDefault];
[notificationCategory setActions:#[notificationAction1,notificationAction2] forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObjects:notificationCategory, nil];
UIUserNotificationType notificationType = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:notificationType categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
// [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:categories]];
NSDictionary *payload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (payload)
NSLog(#"payload is : %#", payload);
return YES;
}

iOS - Trigger Local Notification when message is received

I'm building an app that allows its users to send each other messages. When a new message is received, it appears in the current user's Table view. I want my app to send the current user a notification when a new message arrives. Does anyone know how I might go about doing this?
I have notifications set up in my AppDelegate already:
appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Let the device know we want to receive push notifications
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
and I know the below code will allow me to fire a notification at a specified time (e.g. set by a picker):
// Get the current date
NSDate *pickerDate = [self.datePicker date];
// Schedule the notification
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = pickerDate;
localNotification.alertBody = self.itemText.text;
localNotification.alertAction = #"You are being notified!";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// Request to reload table view data
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
// Dismiss the view controller
[self dismissViewControllerAnimated:YES completion:nil];
How do I make a notification occur however when a new message is posted to the server (and appears in the tableview) for the logged in user?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];}
If your system is iOS8, you need to register permission.
UILocalNotification * notification = [[UILocalNotification alloc] init];
NSDate * pushDate = [NSDate dateWithTimeIntervalSinceNow:Time];
if (notification!=nil) {
notification.fireDate= pushDate;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.repeatInterval = kCFCalendarUnitDay;
notification.soundName = UILocalNotificationDefaultSoundName;
notification.alertBody = #"Time O.K!";
NSLog(#"Ready");
notification.applicationIconBadgeNumber = 1;
//notification.applicationIconBadgeNumber = [[[UIApplication sharedApplication] scheduledLocalNotifications] count]+1;
NSDictionary * inforDic = [NSDictionary dictionaryWithObject:#"name" forKey:#"key"];
notification.userInfo =inforDic;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
You can have a try,this code I can successfully use on my device.

Local Notification Not Firing With Background Fetch

Can someone please take a look at the following code and tell me why the local notification isn't firing. Im running the app in XCode and using the debug option to simulate a background fetch but the local notification doesn't fire.
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(#"performFetchWithCompletionHandler");
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif) {
localNotif.alertBody = #"Update demo text!";
localNotif.alertAction = #"OK";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.fireDate = nil;
NSLog(#"Local Notification");
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
//Perform some operation
completionHandler(UIBackgroundFetchResultNewData);
}
Do you query the user to allow push?
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}
Instead of checking device version, use below code that checks RespondToSelector:
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)])
{
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}

iOS 8 notification action button not displayed

I am trying to send a local notification with a action button.
The notification is ok. But the action button is not displayed.
I am using Xcode 6.3.2 iPhone 6 iOS 8.2
Sending notification
UIApplication *myapp = [UIApplication sharedApplication];
UILocalNotification *test = [[UILocalNotification alloc] init];
if(test) {
NSLog(#"Sending notification");
test.alertBody = #"jothi test alert";
test.alertTitle = #"kottapa";
test.soundName = UILocalNotificationDefaultSoundName;
test.alertAction = NSLocalizedString(#"View Details", nil);
test.category = #"MY_CATEGORY";
[myapp presentLocalNotificationNow:test];
}
in app delegate didFinishLaunchingWithOptions:
UIMutableUserNotificationAction *myAction =
[[UIMutableUserNotificationAction alloc] init];
myAction.identifier = #"MY_IDENTIFIER";
myAction.title = #"Test Action";
myAction.activationMode = UIUserNotificationActivationModeBackground;
myAction.destructive = NO;
myAction.authenticationRequired = NO;
//------------
// First create the category
UIMutableUserNotificationCategory *inviteCategory =
[[UIMutableUserNotificationCategory alloc] init];
// Identifier to include in your push payload and local notification
inviteCategory.identifier = #"MY_CATEGORY";
// Add the actions to the category and set the action context
[inviteCategory setActions:#[myAction]
forContext:UIUserNotificationActionContextDefault];
// Set the actions to present in a minimal context
[inviteCategory setActions:#[myAction]
forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObject:inviteCategory];
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound
categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
Your code works, you just needs to swipe the notification to the left in order to see the action button (or pull it down, if it's presented in a form of a banner from the top, when the device isn't locked).
Also, I'm guessing you already did that but just didn't include the code, in order to handle the action the user chose, you need to implement this method in your app delegate:
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler

Resources