LocalNotification for iOS - ios

I am implementing local notifications in my iOS app. Actually, I have a implementation with a method when i have created a notification :
-(void)setAlarmAction: (NSDate *) notificationDay days: (NSNumber *) day alert : (NSNumber * ) priority name:(NSString * ) nameNotification {
NSDate *notificationDate = notificationDay;
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
if (localNotification == nil) {
return;
}
localNotification.fireDate = notificationDate;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = [NSString stringWithFormat: #"Quedan %# dias" , day];
localNotification.alertAction = #"Ver Documento";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1; //aumenta en uno el numero de notificaciones
////////////
NSDictionary *infoDictionary = [NSDictionary dictionaryWithObject:#"notification" forKey:nameNotification]; //1º que se guarda , 2º con que clave
localNotification.userInfo = infoDictionary;
////////////
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:localNotification];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:nameNotification];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// Get list of local notifications
NSArray *localNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
for( UILocalNotification * local in localNotifications) {
NSLog(#"Notificacion: %# fecha :%#",local.alertBody,local.fireDate.description);
}
}
-(void) launchNotificacion:(Documento *)document {
self.txDate.text = document.text;
}
I want the app run in background and when it appear on the tabBar, i can push it and it go me to a concret view and launch a few data. I did it in the didFinishlaunchingWithOptions.
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//self.viewDocumentForm
VTDocumentFormViewController *VTDocument = [[VTDocumentFormViewController alloc] initWithNibName:#"VTDocumentFormViewController" bundle:nil];
UILocalNotification *notification = [launchOptions objectForKey:
UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
[self.window.rootViewController presentViewController: VTDocument animated:YES completion:nil];
Documento *reminderDocument = [NSEntityDescription insertNewObjectForEntityForName:#"Documento" inManagedObjectContext:self.managedObjectContext];
reminderDocument = [notification.userInfo objectForKey: key ];
[self.viewDocumentForm launchNotificacion:reminderDocument];
application.applicationIconBadgeNumber = notification.applicationIconBadgeNumber-1;
}
// Override point for customization after application launch.
return YES;
}
But it doesn't work and i don't know the reason. Please, help.

didFinishLaunchingWithOptions: with UIApplicationLaunchOptionsLocalNotificationKey in launchOptions will be invoked only if app was suspended/killed before localNotification.fireDate reached.
If you'r app is just in background (not killed) or active you'll got
application:didReceiveLocalNotification: fired
Also i don't see in your didFinishLaunchingWithOptions: where did you register user notification settings (for iOS8)… smth like:
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge;
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
}

Related

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.

Notification fireTime not working. Sends notifications immediately in ios

I have used the following code to send the local notification in particular time. It works fine when calling from a method but when i am calling from another method its not working.
Code as follows:
-(void)notificationUserInfo:(NSDictionary *)notificationData
{
UILocalNotification *notification = [[UILocalNotification alloc] init];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd/MM/yyyy HH:mm"];
NSString *tipid = [notificationData objectForKey:#"receivedTipsId"];
NSString *currentDate = [notificationData objectForKey:#"receivedDate"];
NSString *tipsCategoryid = [notificationData objectForKey:#"categoryId"];
NSString *todayDateTime = [notificationData objectForKey:#"todayDate"];
NSString *categoryName = [notificationData objectForKey:#"categoryName"];
NSString *tipsForNotification = [notificationData objectForKey:#"tipsForNotification"];
NSString *cardType = [notificationData objectForKey:#"cardType"];
//Assigning the notification contents
NSDate *updatedDateFormat = [dateFormat dateFromString:todayDateTime];
notification.fireDate = updatedDateFormat;
notification.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:tipid, #"receivedTipsId", currentDate, #"receivedDate", tipsCategoryid, #"categoryId", cardType, #"cardType", nil];
notification.alertBody = [NSString stringWithFormat:#"%#: %#",categoryName, tipsForNotification];
notification.soundName = UILocalNotificationDefaultSoundName;
notification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
Thanks in advance.
If you are using this in iOS 8 then you have to register your app for local notification.
IN app delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /*...*/ }
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
}
And then
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
if (!localNotification) {
break;
}
**localNotification.timeZone = [NSTimeZone defaultTimeZone];**
[localNotification setFireDate:[NSDate dateWithTimeIntervalSinceNow:20]];
localNotification.alertBody = #"message";
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
Use above code.
This is because of problem with time and date format. When i used this method, I have given the firedate as past date. eg., instead of dd/MM/yyyy i used MM/dd/yyyy.
So 11/12/2014 is returned as 12/11/2014. So the notification is received immediately after the notification scheduled.

Premeditated Notifications

Is it possible to setup an app to send notifications from it's self at specified times? Perhaps by putting them in a queue? As of now I'm having to go through a push notification server and that seems like over kill when I'm sending messages out every Tuesday morning. Also, what is this called (so I can better research it on the web)
You can schedule notification like this:
- (void)scheduleNotification
{
//Cancel all previous Local Notifications
[[UIApplication sharedApplication] cancelAllLocalNotifications];
//Set new Local Notifications
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil)
{
UILocalNotification *notif = [[cls alloc] init];
//3 days
notif.fireDate = [NSDate dateWithTimeInterval:60.0f*60.0f*24.0f*3.0f sinceDate:[NSDate date]];
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Come Back Again! Lets blast All Zombie!";
notif.alertAction = #"PLAY";
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application registerForRemoteNotificationTypes:
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound];
[self scheduleNotification];
..
}

Is NSNotificationCenter necessary to cancel UILocalnotficiation?

I want to cancel a UILocalnotification , when i cancel notification still the notification is being fired . I wanted to know do i have to call any delegate method in appdelegate to cancel notification .the code which i am using is executing correctly .but the notification is getting fired .
Should i use NSNotification center which has removeObserver method to cancel uilocalnotification.
Does UILocalnotification fires notification from the app or from the device.
UPDATE - This is how i am scheduling my notification
-(UILocalNotification *)scheduleNotification :(int)remedyID
{
NSString *descriptionBody;
NSInteger frequency;
UILocalNotification *notif = [[UILocalNotification alloc] init];
NSLog(#"%d",remedyID);
descriptionBody =[[self remedyDetailsForRemedyID:remedyID] objectForKey:#"RemedyTxtDic"];
frequency = [[[self remedyDetailsForRemedyID:remedyID] objectForKey:#"RemedyFrequency"]intValue];
NSArray *notificationFireDates = [self fireDatesForFrequency:frequency];
for (NSDate *fireDate in notificationFireDates)
{
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.repeatInterval = NSDayCalendarUnit;
notif.alertBody = [NSString stringWithString:descriptionBody];
notif.alertAction = #"Show me";
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = 1;
notif.fireDate = fireDate;
NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:notif.alertBody, #"kRemindMeNotificationDataKey", [NSNumber numberWithInt:remedyID],kRemindMeNotificationRemedyIDKey,
nil];
notif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
}
return notif;
}
Cancelling notification
- (void)cancelNotification:(int)remedyId
{
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
NSLog(#"Cancelling... Before %d",[[[UIApplication sharedApplication]scheduledLocalNotifications]count]);
for (UILocalNotification *notification in notifications)
{
int notifRemedyId = [[notification.userInfo objectForKey:#"kRemindMeNotificationRemedyIDKey"]intValue];
NSLog(#"remedyID : %d",remedyId);
NSLog(#"notifyId : %d",notifRemedyId);
if (remedyId == notifRemedyId) {
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
NSLog(#"Cancelling... After %d",[[[UIApplication sharedApplication]scheduledLocalNotifications]count]);
}
NSNotification center which has removeObserver method to cancel uilocalnotification.
NSNotificationCenter has nothing to do with UILocalNotification. I'm sorry that they both use "notification" somewhere in their names, but that is just coincidence really.
scheduledLocalNotifications will give you the list of all scheduled notifications and use
- (void)cancelLocalNotification:(UILocalNotification *)notification
or you can cancel them all using:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Edit :
NSString *notifRemedyId = #"notifRemedyId";
UILocalNotification *localnotif=[[UILocalNotification alloc]init];
NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:#"kRemindMeNotificationRemedyIDKey", kRemindMeNotificationRemedyIDKey,YOUR_REMEDYID,#"notifRemedyId",nil];
localnotif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localnotif];
Cancel as :
for (UILocalNotification *aNotif in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
if ([[aNotif.userInfo objectForKey: kRemindMeNotificationRemedyIDKey] isEqualToString:#"kRemindMeNotificationRemedyIDKey"]) {
if (remedyId == [[aNotif.userInfo objectForKey: kRemindMeNotificationRemedyIDKey] intValue]) {
[[UIApplication sharedApplication] cancelLocalNotification:aNotif];
break;
}
}
}
Hope it helps you.

Resources