iOS Custom Action When Opening Notification - ios

I know that I can set actions for an iOS notification like:
UIMutableUserNotificationAction *acceptAction =
[[UIMutableUserNotificationAction alloc] init];
acceptAction.identifier = #"THANKS_IDENTIFIER";
acceptAction.title = #"View News Page";
// Given seconds, not minutes, to run in the background
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
acceptAction.destructive = NO;
acceptAction.authenticationRequired = NO;
UIMutableUserNotificationCategory *inviteCategory =
[[UIMutableUserNotificationCategory alloc] init];
inviteCategory.identifier = #"TAGGED_CATEGORY";
[inviteCategory setActions:#[acceptAction]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObjects:inviteCategory, nil];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:categories];
[[UIApplication sharedApplication]
registerUserNotificationSettings:settings];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
and include in the payload of the aps a category matching what is listed here, and when the app receives a notification of said category, it will add the action to it, and when that action button is pressed, perform the action here:
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)notification
completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:#"THANKS_IDENTIFIER"]) {
[self handleAcceptActionWithNotification:notification];
}
// Must be called when finished
completionHandler();
}
-(void) handleAcceptActionWithNotification:(NSDictionary *)notification {
UIAlertView *test = [[UIAlertView alloc] initWithTitle:#"YAY" message:#"Success" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[test show];
[self.tabBarController setSelectedIndex:1];
[self performSelector:#selector(launchNews) withObject:nil afterDelay:1.0];
}
-(void)launchNews {
NewsViewController *dvController8 = [[NewsViewController alloc] initWithNibName:#"NewsViewController" bundle:[NSBundle mainBundle]];
[self.tabBarController.navigationController pushViewController:dvController8 animated:YES];
[dvController8 release];
}
However, is there a way that when a push notification of a certain category is received it performs a custom action, without the need of adding in an action button to the notification?
Here is my Payload, using cloudCode:
Parse.Cloud.define("newNews", function(request, response) {
var theTitle = request.params.articleTitle;
var pushQuery = new Parse.Query(Parse.Installation);
Parse.Push.send({
where: pushQuery,
data: {
alert: "A new article, \"" + theTitle + "\" was just posted. Open app to view.",
category : "TAGGED_CATEGORY",
sound: "default.caf"
}
}).then(function() {
response.success("Push was sent successfully.")
}, function(error) {
response.error("Push failed to send with error: " + error.message);
});
});
UPDATED CODE:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[PFPush handlePush:userInfo];
if (application.applicationState == UIApplicationStateInactive) {
[self handleRemoteNotificationWithPayload:userInfo];
}
}
-(void)handleRemoteNotificationWithPayload:(NSDictionary *)payload {
NSString *thePayload = [payload valueForKey:#"category"];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Hi" message:thePayload delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alertView show];
if ([thePayload isEqualToString:#"TAGGED_CATEGORY"]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Hi" message:#"Received with category" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alertView show];
[self.tabBarController setSelectedIndex:4];
}
}

Related

actions not showing in local notification

I am trying to generate a local notification with 2 actions. However, even though the notifications are popping up. I am not able to see the actions.
Is this because of something new in iOS 10
my viewcontroller,h has code:
-(void)createNotifications: (int)seconds{
UILocalNotification *local = [[UILocalNotification alloc]init];
local.fireDate = [[NSDate date]dateByAddingTimeInterval:seconds];
local.timeZone = nil;
local.alertBody = #"Alert body";
local.alertTitle = #"Alert Title";
local.alertAction = #"Okay";
local.soundName = UILocalNotificationDefaultSoundName;
local.applicationIconBadgeNumber = 4127;
local.category = #"MAIN_CATEGORY";
[[UIApplication sharedApplication] scheduleLocalNotification:local];
}
-(void)requestPermissionToNotify{
UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc]init];
action.identifier = #"FLOAT_ACTION";
action.title = #"float";
action.activationMode = UIUserNotificationActivationModeBackground;
action.destructive = YES;
action.authenticationRequired = NO;
UIMutableUserNotificationAction *stingAction = [[UIMutableUserNotificationAction alloc]init];
stingAction.identifier = #"STING_ACTION";
stingAction.title = #"sting";
stingAction.activationMode = UIUserNotificationActivationModeForeground;
stingAction.destructive = NO;
stingAction.authenticationRequired = NO;
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc]init];
category.identifier = #"MAIN_CATEGORY";
NSSet *categories = [NSSet setWithObjects:category, nil];
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[category setActions:#[action,stingAction] forContext:UIUserNotificationActionContextDefault];
}
my appdelegate.m has callback handlers:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
application.applicationIconBadgeNumber = 0;
UILocalNotification *localnotif = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if(localnotif){
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Received while launch" message:localnotif.alertBody preferredStyle:UIAlertViewStyleDefault];
UIAlertAction *aa = [UIAlertAction actionWithTitle:#"okay" style:UIAlertViewStyleDefault handler:nil];
[alert addAction:aa];
dispatch_async(dispatch_get_main_queue(), ^{
[application.keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
});
}
return YES;
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
application.applicationIconBadgeNumber = 0;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Received while running" message:notification.alertBody preferredStyle:UIAlertViewStyleDefault];
UIAlertAction *aa = [UIAlertAction actionWithTitle:#"okay" style:UIAlertViewStyleDefault handler:nil];
[alert addAction:aa];
dispatch_async(dispatch_get_main_queue(), ^{
[application.keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
});
}
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Received while action" message:identifier preferredStyle:UIAlertViewStyleDefault];
UIAlertAction *aa = [UIAlertAction actionWithTitle:#"okay" style:UIAlertViewStyleDefault handler:nil];
[alert addAction:aa];
dispatch_async(dispatch_get_main_queue(), ^{
[application.keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
});
completionHandler();
}
You might be going in the wrong direction for adding action in the local notification. You need to add category along with action identifier while asking for permission. Please check below code for adding action and handling action tap in notification
// Ask for permission to allow Notification
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"10.0")){
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNNotificationAction *action = [UNNotificationAction actionWithIdentifier:#"ActionIdentifier" title:#"NewAction" options:UNNotificationActionOptionNone];
NSArray *notificationActions = #[action];
UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:#"Notification" actions:notificationActions intentIdentifiers:#[] options:UNNotificationCategoryOptionCustomDismissAction];
NSSet *categories = [NSSet setWithObject:category];
[center setNotificationCategories:categories];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!granted) {
}
}];
}
else {
UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init];
action.identifier = #"ActionIdentifier";
action.title = #"NewAction";
action.activationMode = UIUserNotificationActivationModeBackground;
action.destructive = NO;
action.authenticationRequired = NO;
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
category.identifier = #"ActionIdentifier";
[category setActions:#[action] forContext:UIUserNotificationActionContextDefault];
[category setActions:#[action] forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObjects:category, nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:categories]];
}
// Handle Notification for iOS 10
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
// Handle Notification here
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler {
NSString *actionIdentifier = response.actionIdentifier;
BOOL newActionTapped = [actionIdentifier isEqualToString:#"NewAction"];
if(snooze) {
// Handle NewAction action button here
}
else {
// Handle Notification here
}
completionHandler();
}
// Handle Notification for iOS 9 or lower
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// Handle Notification here
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler {
// This method will be called when user tap on Action
// Handle NewAction action button here
if (completionHandler) {
completionHandler();
}
}

Displaying alert from app delegate before displaying alert from viewDidload

I am attempting to display the message contained within a push notification through the app delegate as outlined in the parse.com documentation.
The problem I am having is that in my viewdidload method for my first view controller, i am presenting an alert which the user MUST see before they use the app.
How can I call the method from my app delegate after the user sees the Alert from the viewdidload method?
EDIT:
So i have, as suggested in the comments, added a global Variable which i set to true once i have Displayed the alert from my ViewDidload method, but the Notification Alert from my appDelegate still does not appear.
here is my app delegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[Parse setApplicationId:#"xxxxxxxxxxxxxxxx"
clientKey:#"xxxxxxxxxxxx"];
// Register for Push Notitications, if running iOS 8
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else {
// Register for Push Notifications before iOS 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound)];
}
return YES;
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (Notification == true) {
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
And here is my viewdidload method:
RoadSafetyAppAppDelegate *AppDelegate;
- (void)viewDidLoad
{
AppDelegate = (RoadSafetyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
backgroundImage.alpha = 0.3;
toRecipients = [[NSArray alloc]initWithObjects:#"records#shellharbour.nsw.gov.au", nil];
static int appCounter;
if ( appCounter < 1 ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
[alert show];
appCounter = appCounter+1;
AppDelegate.NotificationAlert = #"1";
AppDelegate.Notification = true;
}
}
since you want to show the disclaimer ONE time and to be sure that the user saw it and TAPED on Agree Button before showing any notification. you can do that using a simple local notification.
in delegate (...didFinishLaunchingWithOptions:)
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==nil)
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]){ //YES
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
NSString *value=[NSString stringWithFormat:#"%#",[notification.userInfo valueForKey:#"key"]];
if ([value isEqualToString:#"disclaimerShown"]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
///continue handle parse.com notification
}
}
in you ViewController:
-(void)viewDidLoad{
//...
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==NO){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
alert.tag = 1;
[alert show];
}
//...
}
pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 1) {//the disclaimer alert
if (buttonIndex == 0) {
UILocalNotification *alarm = [[UILocalNotification alloc] init];
alarm.userInfo = #{#"key": #"disclaimerShown"};
alarm.fireDate = [NSDate date];
alarm.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
}
}
}
Instead of AppDelegate bool flag property use NSUserDefaults;
In AppDelegate update this line from:
if (Notification == true)
to
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"Notification"] == YES)
And in ViewController -> viewDidLoad method update line from:
AppDelegate.Notification = true;
to
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Notification"];
[[NSUserDefaults standardUserDefaults] synchronize];
Hope this helps.

Create Local Notification on iphone

I am trying to create a local Notification button like "Are you sure you want to delete yes or no? How would I go about doing this
try this :
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert!" message:#"Are you sure you want to delete?" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Yes", #"No", nil];
alert.tag=1;
[alert show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(alertView.tag==1)
{
if(buttonIndex==0)
{
//Do when click "Yes" button
}
else if(buttonIndex==1)
{
//Do when click "No" button
}
}
}
may be it will help you.
Based on what you are trying to accomplish, I do not think you want to use a UILocalNotification, looks like what you want is a UIAlertView
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"My title" message:#"Are you sure you want to delete?" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Yes", #"No", nil];
[alert show];
Hope that helps
You can use a UIAlertView for what you want to do, just like Oscar Gomez says.
To add actions to the buttons first implement the UIAlertViewDelegate and use the method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
You can check the buttonIndex and perform the appropriate action, ( index 0 for button
"Yes" and 1 for button "No").
This code block in AppDelegate file :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
// Override point for customization after application launch.
return YES;
}
// This code block is invoked when application is in foreground (active-mode)
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
**UIAlertView *notificationAlert = [[UIAlertView alloc] initWithTitle:#“Alert” message:#“Are you sure you want to delete?” delegate:self cancelButtonTitle:nil otherButtonTitles:#“Yes”,#“No”, nil];
notificationAlert.tag = 101;
[notificationAlert show];**
// NSLog(#"didReceiveLocalNotification");
}
**- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(alertView.tag==1) {
if(buttonIndex==0)
{
//Do when click "Yes" button
}
else if(buttonIndex==1)
{
//Do when click "No" button
}
}
}**
This code block in .m file of any ViewController :
-(IBAction)startLocalNotification { // Bind this method to UIButton action
NSLog(#"startLocalNotification");
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:7];
notification.alertBody = #"This is local notification!";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
notification.applicationIconBadgeNumber = 10;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
The above code display an AlertView after time interval of 7 seconds when pressed on button that binds “startLocalNotification”.
If application is in background then it displays BadgeNumber as 10 and with default notification sound.

Objective c cancelAllLocalNotifications doesn't work when app was in background

[[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];
}
}
}

Iphone presentLocalNotificationNow not triggering alert and sound while app in background

I have an App registers for location updates, running tests, sometime when I enter a region while the app is in the background I receive a alarm notification with sound. sometime I only see the notification in notification center, and i did not receive any sound and alert...
What can you do to always get the sound and the alert notification ?
this is what i have in my view
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = nil;
localNotif.hasAction = YES;
localNotif.alertBody = fbName;
localNotif.alertAction = #"View";
localNotif.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication]presentLocalNotificationNow:localNotif];
and this is the app delegate
- (void)application:(UIApplication *)application didReceiveLocalNotification (UILocalNotification *)notification
{
if (notification)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Alert"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
facebook = [[Facebook alloc] initWithAppId:kAppId andDelegate:self];
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Alert"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
return YES;
}
If the application is running in the background, the local notification will not get an alert or sound, as it is directly received by your application. In that case, you need to present the notification using presentLocalNotificationNow.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState applicationState = application.applicationState;
if (applicationState == UIApplicationStateBackground) {
[application presentLocalNotificationNow:notification];
}
}

Resources