I've got notifications with some actions; now if there's only one action for a notification, it displays the "alert view" with a dismiss and an options button. When pressing the options, I get 'Open', 'My Action' and 'Close'.
How can I achieve to avoid the options menu and get 'Dismiss' and 'My Action' right from the beginning?
I'm talking about the alert that appears e.g. when you're on the iPhone home screen and you have selected alert style "Alerts" for "Alert Style When Unlocked"
I've got a local push notification with just one action defined. Now I would expect to get the notification on the Home Screen with "Close" on the left and my defined action on the right. But instead I get this one:
I would love to avoid the additional step of tapping "Options" and then only get one real option.
The code I'm using:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil) {
return;
}
localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:NOTIFICATION_DELAY];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = text;
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
localNotif.category = ERROR_CATEGORY;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
registering for push notifications:
UIMutableUserNotificationAction *callSupportAction = [self actionWithIdentifier:#"callSupportAction" title:NSLocalizedString(#"callSupportActionTitle", #"") background:YES destructive:NO authenticationRequired:NO];
UIMutableUserNotificationCategory *errorCategory = [self categoryWithIdentifier:ERROR_CATEGORY actions:#[callSupportAction]];
NSSet *categories = [NSSet setWithObjects:errorCategory, nil];
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
- (UIMutableUserNotificationAction *)actionWithIdentifier:(NSString *)identifier title:(NSString *)title background:(BOOL)background destructive:(BOOL)destructive authenticationRequired:(BOOL)authenticationRequired {
UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init];
action.identifier = identifier;
action.title = title;
action.activationMode = background ? UIUserNotificationActivationModeBackground : UIUserNotificationActivationModeForeground;
action.destructive = destructive;
action.authenticationRequired = authenticationRequired;
return action;
}
- (UIMutableUserNotificationCategory *)categoryWithIdentifier:(NSString *)identifier actions:(NSArray *)actions {
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
category.identifier = identifier;
if (actions.count > 2) {
[category setActions:actions forContext:UIUserNotificationActionContextDefault];
[category setActions:[actions subarrayWithRange:NSMakeRange(0, 2)] forContext:UIUserNotificationActionContextMinimal];
} else {
[category setActions:actions forContext:UIUserNotificationActionContextDefault];
}
return category;
}
Related
I create UILocalNotification and UIMutableUserNotificationAction
if I use iphone, this action button it seems BUT I use ipad this action button does not seems
UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc]init];
action.identifier = #"ActionNotification";
action.title = #"START";
action.activationMode = UIUserNotificationActivationModeForeground;
UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc]init];
categorys.identifier = #"alert";
[categorys setActions:#[action] forContext:UIUserNotificationActionContextMinimal];
UIUserNotificationSettings *setings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:[NSSet setWithObjects:categorys, nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
[[UIApplication sharedApplication] registerUserNotificationSettings:setings];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = aIntervalDate;
//localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
localNotification.alertBody =#"Notification Test";
localNotification.alertAction=#"START";
localNotification.category=#"alert";
localNotification.soundName = #"Reminder_Sound.mp3";
localNotification.applicationIconBadgeNumber=1;
// localNotification.hasAction=YES;
NSDictionary *infoDict = #{#"title" : #"xxxxxx",
#"tipi" : #"yyyyy"};
localNotification.userInfo = infoDict;
localNotification.timeZone = [NSTimeZone systemTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
Actually I want to show a local notification in my app. But i want to show this notification with some custom design like ok and cancel button on it.And on the click of Ok and Cancel i want to perform some actions.Please suggest something.
Thanks In advance.
i am impliment this code for custom local notification may be helping you
where Accept is identifier where you get in delegates of local notification in appDelegate.m
NSString *idetnt = #"Accept";
NSString *idetnt1 = #"Reject";
NSString *idetnt2 = #"Local Notification";
UIMutableUserNotificationAction *notificationAction1 = [[UIMutableUserNotificationAction alloc] init];
notificationAction1.identifier = idetnt;
notificationAction1.title = #"Snooze";
notificationAction1.activationMode = UIUserNotificationActivationModeBackground;
notificationAction1.destructive = NO;
notificationAction1.authenticationRequired = NO;
UIMutableUserNotificationAction *notificationAction2 = [[UIMutableUserNotificationAction alloc] init];
notificationAction2.identifier = idetnt1;
notificationAction2.title = #"Call";
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];
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:600];
localNotification.alertBody = idetnt2;
localNotification.category = #"Email";
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
when ur app in background then this methods call
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler
{
if ([identifier isEqualToString:#"Accept"])
{
}
else if ([identifier isEqualToString:#"Reject"])
{
}
else if ([identifier isEqualToString:#"Reply"])
{
}
if(completionHandler != nil)
completionHandler();
}
when ur app in foreground then this methods call
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification
{
}
Go to capability option and click on remote notification
You can't add full customisation, but your notifications can set the category property to specify which notification settings should be used and those notification settings can specify which buttons to show and what those buttons to when the user selects them.
I am implementing a local notification method but I recieved that warning
Warning: Application delegate received call to -application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler: but the completion handler was never called.
Here is my code in didfinishlaunchmethod
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIMutableUserNotificationAction *snooze=[[UIMutableUserNotificationAction alloc] init];
[snooze setActivationMode:UIUserNotificationActivationModeBackground];
[snooze setTitle:#"Snooze"];
[snooze setIdentifier:NotificationActionOneIdent];
[snooze setDestructive:NO];
[snooze setAuthenticationRequired:YES];
UIMutableUserNotificationAction *cancel=[[UIMutableUserNotificationAction alloc] init];
[cancel setActivationMode:UIUserNotificationActivationModeBackground];
[cancel setTitle:#"Cancel"];
[cancel setIdentifier:NotificationActionTwoIdent];
[cancel setDestructive:NO];
[cancel setAuthenticationRequired:YES];
UIMutableUserNotificationCategory *actionCategory;
actionCategory = [[UIMutableUserNotificationCategory alloc] init];
[actionCategory setIdentifier:NotificationCategoryIdent];
[actionCategory setActions:#[cancel, snooze]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObject:actionCategory];
UIUserNotificationType types = (UIUserNotificationTypeAlert|
UIUserNotificationTypeSound|
UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings;
settings = [UIUserNotificationSettings settingsForTypes:types
categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
and here is code for completion handler
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler
{
NSLog(#"called");
if ([identifier isEqualToString:NotificationActionOneIdent]) {
NSLog(#"You choose snooze");
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil) return;
NSDate *fireTime = [[NSDate date] dateByAddingTimeInterval:900];
localNotif.fireDate = fireTime;
localNotif.alertBody = #"Time to wake up";
localNotif.repeatInterval=kCFCalendarUnitMinute;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
else if ([identifier isEqualToString:NotificationActionTwoIdent]) {
NSLog(#"You choose cancel");
}
completionHandler();
}
But i am geeting same warning again and again.. please help me with this issue.
you have an exit point in the handle function that does not call the completionHandler()
if (localNotif == nil) return;
Fix this and the error should go away.
if (localNotif != nil) {
NSDate *fireTime = [[NSDate date] dateByAddingTimeInterval:900];
localNotif.fireDate = fireTime;
localNotif.alertBody = #"Time to wake up";
localNotif.repeatInterval=kCFCalendarUnitMinute;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
I'm trying to schedule an interactive UILocalNotifaction.
My attempt has been to use the following code, which I grabbed from this tutorial:
NSString * const NotificationCategoryIdent = #"ACTIONABLE";
NSString * const NotificationActionOneIdent = #"ACTION_ONE";
NSString * const NotificationActionTwoIdent = #"ACTION_TWO";
- (void)registerForNotification {
UIMutableUserNotificationAction *action1;
action1 = [[UIMutableUserNotificationAction alloc] init];
[action1 setActivationMode:UIUserNotificationActivationModeBackground];
[action1 setTitle:#"Action 1"];
[action1 setIdentifier:NotificationActionOneIdent];
[action1 setDestructive:NO];
[action1 setAuthenticationRequired:NO];
UIMutableUserNotificationAction *action2;
action2 = [[UIMutableUserNotificationAction alloc] init];
[action2 setActivationMode:UIUserNotificationActivationModeBackground];
[action2 setTitle:#"Action 2"];
[action2 setIdentifier:NotificationActionTwoIdent];
[action2 setDestructive:NO];
[action2 setAuthenticationRequired:NO];
UIMutableUserNotificationCategory *actionCategory;
actionCategory = [[UIMutableUserNotificationCategory alloc] init];
[actionCategory setIdentifier:NotificationCategoryIdent];
[actionCategory setActions:#[action1, action2]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObject:actionCategory];
UIUserNotificationType types = (UIUserNotificationTypeAlert|
UIUserNotificationTypeSound|
UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings;
settings = [UIUserNotificationSettings settingsForTypes:types
categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
However, this code doesn't seem to actually schedule the notification anywhere. What am I missing?
Apollo,
Scheduling a local notification is relatively easy. Piggy backing off the tutorial you referenced I kind of switched it up so it can make more sense, you can deter or alter the code as need be, but this will give you a better starting point than the tutorial did. Please know it's not mandatory to put this in application didFinishLaunchingWithOptions: you can schedule a UILocalNotification anywhere app-wide. See the references below for complete properties of each method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Here we are just going to create the actions for the category.
UIMutableUserNotificationAction *acceptAction = [self createAction];
UIMutableUserNotificationAction *laterAction = [self createLaterAction];
laterAction.title = #"Not Now";
//Creating the category and assigning the actions:
UIMutableUserNotificationCategory *acceptCategory = [self createCategory:#[acceptAction, laterAction]];
//Register the categories
[self registerCategorySettings:acceptCategory];
//For testing purposes we will just fire a local notification on load. This is just for reference, but you don't have to call it in applicationDidFinishLaunching
[self fireLocalNotification];
return YES;
}
//Create a category
- (UIMutableUserNotificationCategory *)createCategory:(NSArray *)actions {
UIMutableUserNotificationCategory *acceptCategory = [[UIMutableUserNotificationCategory alloc] init];
acceptCategory.identifier = #"ACCEPT_CATEGORY";
[acceptCategory setActions:actions forContext:UIUserNotificationActionContextDefault];
return acceptCategory;
}
//Register your settings for that category
- (void)registerCategorySettings:(UIMutableUserNotificationCategory *)category {
UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);
NSSet *categories = [NSSet setWithObjects:category, nil];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
//Create Actions Methods
- (UIMutableUserNotificationAction *)createAction {
UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc] init];
acceptAction.identifier = #"ACCEPT_IDENTIFIER";
acceptAction.title = #"Accept";
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
acceptAction.destructive = NO;
// If YES requires passcode
acceptAction.authenticationRequired = NO;
return acceptAction;
}
- (UIMutableUserNotificationAction *)createLaterAction {
UIMutableUserNotificationAction *laterAction = [[UIMutableUserNotificationAction alloc] init];
laterAction.identifier = #"LATER_IDENTIFIER";
laterAction.title = #"Not Now";
laterAction.activationMode = UIUserNotificationActivationModeBackground;
laterAction.destructive = NO;
laterAction.authenticationRequired = NO;
return laterAction;
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
UIUserNotificationType allowedTypes = [notificationSettings types];
NSLog(#"Registered for notification types: %u", allowedTypes);
}
//Fire a local Notification: For testing purposes we are just going to fire this immediately after launch. But this will give you a general idea of how to create a UILocalNotification app-wide:
- (void)fireLocalNotification {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"We are just testing -";
notification.category = #"ACCEPT_CATEGORY";
notification.fireDate = [NSDate dateWithTimeInterval:15 sinceDate:[NSDate date]];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
And your outcome will be as anticipated:
Don't forget to call the completion handlers for the actions that were selected.
application:handleActionWithIdentifier:forLocalNotification:completionHandler:
Please review the documentation and references below for further customization. Again, i'm not saying this is the right way and it's definetly not the only, it's just a great starting point for you to understand how they work. There are lots of customizable properties for actions and UILocalNotifications
REFERENCES
UILocalNotification & Properties : Documentation
iOS8 Notification Actions & Properties : Documentation
I am currently working on interactive iOS notifications made by 8 and honestly, I really struggle to see my buttons.
With the code below, I fail to see my buttons:
//INTERACIVE
UIMutableUserNotificationAction *acceptAction =
[[UIMutableUserNotificationAction alloc] init];
acceptAction.identifier = #"ACCEPT_IDENTIFIER";
acceptAction.title = #"Accept";
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
acceptAction.destructive = NO;
acceptAction.authenticationRequired = NO;
UIMutableUserNotificationAction *maybeAction =
[[UIMutableUserNotificationAction alloc] init];
maybeAction.identifier = #"MAYBE_IDENTIFIER";
maybeAction.title = #"Maybe";
maybeAction.activationMode = UIUserNotificationActivationModeBackground;
maybeAction.destructive = NO;
maybeAction.authenticationRequired = YES;
UIMutableUserNotificationAction *declineAction =
[[UIMutableUserNotificationAction alloc] init];
declineAction.identifier = #"DECLINE_IDENTIFIER";
declineAction.title = #"Decline";
declineAction.activationMode = UIUserNotificationActivationModeBackground;
declineAction.destructive = YES;
declineAction.authenticationRequired = NO;
UIMutableUserNotificationCategory *inviteCategory =
[[UIMutableUserNotificationCategory alloc] init];
inviteCategory.identifier = #"INVITE_CATEGORY";
[inviteCategory setActions:#[acceptAction, maybeAction, declineAction]
forContext:UIUserNotificationActionContextDefault];
[inviteCategory setActions:#[acceptAction, declineAction]
forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObjects:inviteCategory, nil];
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
localNotification.alertBody = #"Testing";
localNotification.category = #"INVITE_CATEGORY"; // Same as category identifier
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
Any Idea for my problem?
Despite all the examples on the Internet, I'm apparently the only one with this problem.
There's a really great tutorial here: The Code Ninja
Everything in your code looks fine. I've gotta ask to make sure you're not just overlooking what actually happens - if you were looking at the notification on the home screen, did you swipe left on the notification to reveal the buttons?
Here is what I am using (sorry about the swift)
Initial Prompt for notifications
var openAction = UIMutableUserNotificationAction()
openAction.identifier = "OPEN_IDENTIFIER"
openAction.title = "Open"
openAction.destructive = false
openAction.authenticationRequired = false
openAction.activationMode = .Foreground
var snoozeAction = UIMutableUserNotificationAction()
snoozeAction.identifier = "SNOOZE_IDENTIFIER"
snoozeAction.title = "Snooze"
snoozeAction.destructive = true
snoozeAction.authenticationRequired = false
snoozeAction.activationMode = .Background
var snoozeable = UIMutableUserNotificationCategory()
snoozeable.identifier = NOTE_SNOOZE_CAT
snoozeable.setActions([openAction, snoozeAction], forContext: .Default)
snoozeable.setActions([openAction, snoozeAction], forContext: .Default)
var notSnoozable = UIMutableUserNotificationCategory()
notSnoozable.identifier = NOTE_NO_SNOOZE_CAT
notSnoozable.setActions([openAction], forContext: .Default)
notSnoozable.setActions([openAction], forContext: .Default)
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Sound | .Alert |
.Badge, categories: NSSet(array:[snoozeable, notSnoozable])
))
Local Notification
var notification = UILocalNotification()
notification.fireDate = fireDate
notification.timeZone = NSTimeZone.defaultTimeZone()
notification.alertBody = "Alert Body"
notification.userInfo = userInfo
notification.category = blnCanSnooze ? NOTE_SNOOZE_CAT : NOTE_NO_SNOOZE_CAT
UIApplication.sharedApplication().scheduleLocalNotification(notification)
I had a different issue. I was dealing with multiple types of notifications. Few of my notifications were not showing action buttons while few were. Found out that only the notification which was set at last was showing action buttons. I was stupid not to think that identifier of category is overridden with the last set notification as the settings are shared.
For dealing with this, we need to extract the current notification settings, add ours to it and set it back again:
NSMutableArray *arrNewCategories = [NSMutableArray new];
UIUserNotificationSettings *oldSettings = [[UIApplication sharedApplication]currentUserNotificationSettings];
for (UIMutableUserNotificationCategory *oldCategory in oldSettings.categories)
{
if (![oldCategory.identifier isEqualToString:newNotificationCategory.identifier])
[arrNewCategories addObject:oldCategory];
}
[arrNewCategories addObject:newNotificationCategory];
UIUserNotificationType notificationType = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *newSettings = [UIUserNotificationSettings settingsForTypes:notificationType categories:[NSSet setWithArray:arrNewCategories]];
[[UIApplication sharedApplication] registerUserNotificationSettings:newSettings];
Just make sure that the identifier of newNotificationCategory matches with your UILocalNotification's category.