I tried a verity of blogs but from some reason it doesn't fire!
Can it be because I don't ask permission? Am I suppose to ask the user for local? I understand from apple's documentation that I don't.
This is my singelton class (Checked it is called - with a breakpoint)
//
// «FILENAME»
// «PROJECTNAME»
//
// Created by «FULLUSERNAME» on «DATE».
// Copyright «YEAR» «ORGANIZATIONNAME». All rights reserved.
// File created using Singleton XCode Template by Mugunth Kumar (http://mugunthkumar.com
// Permission granted to do anything, commercial/non-commercial with this file apart from removing the line/URL above
#import "NotifierSingelton.h"
static NotifierSingelton* _instance;
#implementation NotifierSingelton
+ (NotifierSingelton*)sharedInstance
{
#synchronized(self) {
if (_instance == nil) {
// iOS 4 compatibility check
Class notificationClass = NSClassFromString(#"UILocalNotification");
if(notificationClass == nil)
{
_instance = nil;
}
else
{
_instance = [[super allocWithZone:NULL] init];
}
// Allocate/initialize any member variables of the singleton class her
// example
//_instance.member = #"";
}
}
return _instance;
}
- (void) scheduleNotificationOn:(NSDate*) fireDate
text:(NSString*) alertText
action:(NSString*) alertAction
sound:(NSString*) soundfileName
launchImage:(NSString*) launchImage
andInfo:(NSDictionary*) userInfo
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = fireDate;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = alertText;
localNotification.alertAction = alertAction;
if(soundfileName == nil)
{
localNotification.soundName = UILocalNotificationDefaultSoundName;
}
else
{
localNotification.soundName = soundfileName;
}
localNotification.alertLaunchImage = launchImage;
//self.badgeCount ++;
localNotification.applicationIconBadgeNumber = 1;
localNotification.userInfo = userInfo;
// Schedule it with the app
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[localNotification release];
}
#pragma mark Singleton Methods
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedInstance]retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
#end
I don't really see anything wrong with your code. Make sure your firedate is not null. Here is working code form one of my apps:
notif = [[UILocalNotification alloc] init];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *raceDate = [df dateFromString:[raceDates objectAtIndex:i]];
notif.fireDate = raceDate;
notif.timeZone = [NSTimeZone timeZoneWithName:#"WAT"];
notif.alertBody = NSLocalizedString(#"NotificationBody", #"");
notif.alertAction = NSLocalizedString(#"NotificationButton", #"");
notif.soundName = #"push.aif";
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
[notif release];
Also, I'm not sure if it's required but your app may need to be multi-tasking enabled.
Related
I am trying to cancel a already scheduled notification , notification is getting called but when i try to cancel a notification its not getting cancelled .
NSArray notification contains some random values when there is only one scheduled notification. can anyone help me . I am want to cancel the notification for a particular bookID.
UPDATE :
-(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;
}
- (void)cancelNotification:(int)bookID
{
int notificationBook=0;
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *notification in notifications)
{
int notifBookId = [[notification.userInfo objectForKey:kRemindMeNotificationBookIDKey] intValue];
for (int i=0; i<[bookArray count]; i++)
{
notificationBook =[[[remedyArray objectAtIndex:i] objectForKey:#"BookID"] intValue];
}
NSLog(#"%d",[[notification.userInfo objectForKey:kRemindMeNotificationBookIDKey]intValue]);
NSLog(#"%d",notifBookId);
if (bookId == notifBookId)
{
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
}
NSArray notification contains some random values when there is only one scheduled notification.
It may be due to some previously scheduled notifications of that application already exists. Once try to cancel all the notifications of app starts again
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Your main problem
- (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]; // I change the key value
NSLog(#"remedyID : %d",remedyId);
NSLog(#"notifyId : %d",notifRemedyId);
if (remedyId == notifRemedyId) {
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
NSLog(#"Cancelling... After %d",[[[UIApplication sharedApplication]scheduledLocalNotifications]count]);
}
The key you have given was wrong. I think that was your problem. I figured out one more thing you are scheduling each notification twice i dont know why. Check with that.
You should move the check the inside the loop
for (int i=0; i<[bookArray count]; i++)
{
int bookId =[[[remedyArray objectAtIndex:i] objectForKey:#"BookID"] intValue];
if (bookId == notifBookId)
{
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
I have a table view as follow i did set reminders for each cell using corresponding switch on
-(IBAction)switchingbtn:(id)sender
{
UISwitch *onoff = (UISwitch *) sender;
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if(onoff.on)
{
NSLog(#"Shedule notification");
int tagValue=[sender tag];
NSMutableDictionary *dict = (NSMutableDictionary *)[alarmsArray objectAtIndex:tagValue];
NSDate *firedate = [dict objectForKey:#"date"];
NSLog(#"fire date is %#", firedate);
localNotif.fireDate = firedate;
localNotif.alertBody = #"Start Exercise";
localNotif.applicationIconBadgeNumber = 0;
// localNotif.timeZone =[NSTimeZone timeZoneForSecondsFromGMT:0];
localNotif.timeZone = [NSTimeZone systemTimeZone];
localNotif.repeatInterval = kCFCalendarUnitDay;
// [[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; //**Not working**
[localNotif release];
}
No i need to cancel a preticular 1 noftication for ex 3rd swich cancels 3rd notification
else
{
// Cancel a notification not works
// [[UIApplication sharedApplication] cancelLocalNotification:localNotif];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSLog(#"cancel notification");
}
The best way to cancel single notification so far, is to create an notication that has a userInfo dictionary, in this dictionary you could add a notification ID value for an id key. You keep track of the notifications ID (storing in a plist, sql database, etc) and when you need to delete a notification you just need to ask the UIApplication instance for the scheduled notif and filter by the ID, when you find the match you just need to send the cancel method for that notification.
here is the code which you wanted
- (void)CancelExistingNotification {
//cancel alarm
UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++)
{
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
NSDictionary *userInfoCurrent = oneEvent.userInfo;
NSString *uid=[NSString stringWithFormat:#"%#",[userInfoCurrent valueForKey:#"notificationID"]];
if ([uid isEqualToString:[NSString stringWithFormat:#"%i",self.notificationID]])
{
//Cancelling local notification
[app cancelLocalNotification:oneEvent];
break;
}
}
}
"self.notificationID" comes from a property on a custom object like alarmObject which are loaded with the help NSUserDefaults application wide.
I have this method which adds events to native iphone calendar.
It is already adding monthly reminders successfully - but I want to force any monthy reminders to fall into week days (not weekends).
The NSDictionary model is simply
Id:
Start_Date__c
Finish_Date__c
Payment_Interval__c = Monthly
- (void)addRecurringEventsForPartnership:(NSDictionary *)dict{
ENTER_METHOD;
NSError *error = nil;
EKEvent *startEvent = [EKEvent eventWithEventStore:self.eventStore];
startEvent.calendar = self.defaultCalendar;
startEvent.availability = EKEventAvailabilityFree;
startEvent.startDate = [NSDate dateWithLongFormatString:[dict valueForKey:#"Start_Date__c"]];
startEvent.allDay = YES;
// startEvent.endDate = [startEvent.startDate dateByAddingTimeInterval:30*60];
startEvent.title = [dict theNameValue];
//http://stackoverflow.com/questions/7718006/xcode-why-is-my-event-not-being-added-to-the-calendar
if ([startEvent.startDate isEqualToDate:startEvent.endDate]) {
startEvent.endDate = [startEvent.startDate dateByAddingTimeInterval:30*60];;
}
// if
if ([[dict valueForKey:#"Payment_Interval__c"] isEqualToString:#"Monthly"]) {
EKRecurrenceFrequency freq = EKRecurrenceFrequencyMonthly;
int recurrenceInterval = 1;
EKRecurrenceRule *rule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:freq interval:recurrenceInterval end:nil];
startEvent.recurrenceRule = rule;
startEvent.notes = [NSString stringWithFormat:#"Id:%#",[dict valueForKey:#"Id"]];
// [self.eventStore removeEvent:startEvent span:EKSpanThisEvent error:&error];
[self.eventStore saveEvent:startEvent span:EKSpanThisEvent error:&error];
if (error != nil)
{
DLog(#"WARNING:%#",error.description);
// TODO: error handling here
}
}
// DLog(#"startEvent.endDate:%#",startEvent.endDate);
EKEvent *finishEvent = [EKEvent eventWithEventStore:self.eventStore];
finishEvent.calendar = self.defaultCalendar;
finishEvent.availability = EKEventAvailabilityFree;
finishEvent.startDate = [NSDate dateWithLongFormatString:[dict valueForKey:#"Finish_Date__c"]];
finishEvent.allDay = YES;
finishEvent.title = [NSString stringWithFormat:#"%# - Finish",[dict theNameValue]];
finishEvent.notes = [NSString stringWithFormat:#"Id:%#",[dict valueForKey:#"Id"]];
[self.eventStore saveEvent:finishEvent span:EKSpanThisEvent error:&error];
if (error != nil)
{
DLog(#"WARNING:%#",error.description);
// TODO: error handling here
}
}
Couldn't you use NSDateFormatter to get the numeric day of the week and then adjust by subtracting or adding 1 or 2 depending on which day it returned?
[dateFormatter setDateFormat:#"c"];
Will return numeric (1-7) day of the week, I believe
Here's something that works (at least in iOS7, didn't test on other systems):
EKRecurrenceRule *er = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly interval:1
daysOfTheWeek:#[[EKRecurrenceDayOfWeek dayOfWeek:2], // Monday
[EKRecurrenceDayOfWeek dayOfWeek:3], // Tuesday
[EKRecurrenceDayOfWeek dayOfWeek:4], // Wednesday
[EKRecurrenceDayOfWeek dayOfWeek:5], // Thursday
[EKRecurrenceDayOfWeek dayOfWeek:6]] // Friday
daysOfTheMonth:#[#1, #2]
monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:nil];
event.recurrenceRules = #[er];
I have a transformable attribute on one of my entities, called reminder. It's a UILocalNotification.
Now, since I want to schedule it when it's added, and cancel it when removed, I would like to override the accessors to handle the scheduling and cancelling in there.
How would that look?
Thanks!
Are you actually persisting the UILocalNotification or are you using it as a transient property?
I wouldn't store it, rather UILocalNotification as a userInfo as a property. You can at a key/value pair to that dictionary with information about the owning entity. For instance:
You create a value for the key notificationID in the userInfo dictionary and set a attribute notificationID on your Core Data entity to the same value. That way, you just have to store an int or NSString in your store (which is preferable to transformable).
When you want to fetch your UILocalNotification again you can make an accessor on your Entity Class, something like:
- (void)createNotification
{
static NSUInteger kDeadlineWarningPeriod = 3600;
UILocalNotification *notification = [[UILocalNotification alloc] init];
…
self.notificationID = #"some generated ID";
[notification.userInfo setValue:self.notificationID forKey:#"notificationID"];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
[notification release];
}
- (void)cancelNotification
{
// We search for the notification.
// The entity's ID will be stored in the notification's user info.
[[[UIApplication sharedApplication] scheduledLocalNotifications] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UILocalNotification *notification = (UILocalNotification *)obj;
NSDictionary *userInfo = notification.userInfo;
NSString *notificationID = [userInfo valueForKey:#"notificationID"];
if ([notificationID isEqualToString:self.notificationID])
{
[[UIApplication sharedApplication] cancelLocalNotification:notification];
*stop = YES;
self.notificationID = nil;
}
}];
}
Of course you can make an accessor for your notification in much the same way if you actually need access to the notification object.
Hope it helps.
UPDATE
So since you have a property you call reminder on you Entity (I'm guessing that it is a BOOL) it will look something like this:
// .h
#property (nonatomic, assign) BOOL reminder;
// .m
- (void)setReminder:(BOOL)reminder {
[self willAccessValueForKey#"reminder"];
BOOL hasReminder = [[self primitiveValueForKey:#"reminder"] booleanValue];
[self didAccessValueForKey:#"reminder"];
if (hasReminder && !reminder) {
[self cancelNotification];
}
else if (!hasReminder && reminder) {
[self createNotification];
}
if (reminder != hasReminder)
{
[self willChangeValueForKey:#"reminder"];
[self setPrimitiveValue:[NSNumber numberWithBool:reminder] forKey#"reminder"];
[self didChangeValueForKey:#"reminder"];
}
}
In fact you don't really have to store the "reminder" attribute at all, you can just check if the notificationID attribute is nil or not. That was the idea from my suggestion before.
I haven't checked the code above but I do something similar in two of my projects.
Remember you can get into trouble if you create more than 64 local notifications, since you are only allowed to make that many per app. So you might want to track how many you have before creating any new ones.
If you have only one notification for each object, then you could avoid having to store a notificationID and just use the objectId of the NSManagedObject in the Persistent store.
You can serialize and deserialize the objectId with the following lines of code:
[[self.objectID URIRepresentation] absoluteString]
and
[[self persistentStoreCoordinator] managedObjectIDForURIRepresentation:[NSURL URLWithString:[localNotif.userInfo objectForKey: kYourReminderNotificationKey]
here is the code edited:
- (void)createNotification
{
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil) {
UILocalNotification *notif = [[cls alloc] init];
notif.fireDate = self.dateDue;
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Alert body";
notif.alertAction = #"Show me";
notif.soundName = UILocalNotificationDefaultSoundName;
NSDictionary *userDict = [NSDictionary dictionaryWithObject:[[self.objectID URIRepresentation] absoluteString] forKey:kRemindMeNotificationDataKey];
notif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
}
}
- (void)cancelNotification
{
[[[UIApplication sharedApplication] scheduledLocalNotifications] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UILocalNotification *notification = (UILocalNotification *)obj;
NSDictionary *userInfo = notification.userInfo;
NSString *notificationID = [userInfo valueForKey:kRemindMeNotificationDataKey];
if ([notificationID isEqualToString:[[self.objectID URIRepresentation] absoluteString]])
{
[[UIApplication sharedApplication] cancelLocalNotification:notification];
*stop = YES;
}
}];
}
I am making the application that has needs to set the notification , thankfully i was able t set the local notification but i dont know how to delete the notification which is set by this application(my aplicaton ).The xcode does provide functionality of delete with removeAllNotifications but you cannot remove the selected notifications set by the application
You can call [[UIApplication sharedApplication] cancelLocalNotification:notification] to cancel a notification. Since local notifications conform to the NSCoding protocol, they can be stored and retrieved for later canceling.
I know this post is old but hope this solution helps someone
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for(UILocalNotification *notification in notificationArray){
if ([notification.alertBody isEqualToString:#"your alert body"] && (notification.fireDate == your alert date time)) {
// delete this notification
[[UIApplication sharedApplication] cancelLocalNotification:notification] ;
}
}
I am comparing the alert body and date time just to make sure that i am deleting the right notification since there are chances where two or more notifications can have the same alert body or time.
Local Notification in iOS 10 and Below iOS 10 with Xcode 8 beta 2
pragma mark - Calculate Before Date
-(void) calculateBeforedays:(int)_day hours:(int)_hours minutes:(int) _minutes { //_fir:(int)_firecount
//Get Predefined Future date
NSString *dateString = [NSString stringWithFormat:#"%#T%#:00.000Z",_eventdate,_eventtime];
NSLog(#"dateString %#",dateString);
// NSLog(#"_firecount %d",_firecount);
// //Get Predefined Future date
// NSString *dateString = [NSString stringWithFormat:#"2016-12-31T12:%d:00.000Z",_firecount];
// NSLog(#"dateString %#",dateString);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSDate *marrigeDate = [dateFormatter dateFromString:dateString];
// Set reminder date before marrige date
int setDay = _day;
int setHours = _hours;
int setMins = _minutes;
float milliseconds = (setDay * 24 * 60 * 60 ) + (setHours * 60 * 60 ) + (setMins * 60 );
NSDate *someDateInUTC = [NSDate date];
NSTimeInterval timeZoneSeconds = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate *dateInLocalTimezone = [someDateInUTC dateByAddingTimeInterval:timeZoneSeconds];
//Get Current date
NSDate *currentDate = dateInLocalTimezone;
NSTimeInterval marigeTimeInterval = [marrigeDate timeIntervalSinceDate:currentDate];
//Get difference between time
NSTimeInterval timeIntervalCountDown = marigeTimeInterval - milliseconds;
//Set perticulater timer
NSDate *timerDate = [NSDate dateWithTimeIntervalSinceNow:timeIntervalCountDown];
[self triggerNotification:timerDate];
}
#pragma mark- Trigger Reminders
- (void)triggerNotification:(NSDate *) reminderDate {
if([[[UIDevice currentDevice] systemVersion] floatValue] > 10.0f){
// create actions
#if XCODE_VERSION_GREATER_THAN_OR_EQUAL_TO_8
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
// create actions
UNNotificationAction *acceptAction = [UNNotificationAction actionWithIdentifier:#"com.inviteapp.yes"
title:#"Accept"
options:UNNotificationActionOptionForeground];
UNNotificationAction *declineAction = [UNNotificationAction actionWithIdentifier:#"com.inviteapp.no"
title:#"Decline"
options:UNNotificationActionOptionDestructive];
UNNotificationAction *snoozeAction = [UNNotificationAction actionWithIdentifier:#"com.inviteapp.snooze"
title:#"Snooze"
options:UNNotificationActionOptionDestructive];
NSArray *notificationActions = #[ acceptAction, declineAction, snoozeAction ];
// create a category
UNNotificationCategory *inviteCategory = [UNNotificationCategory categoryWithIdentifier:CYLInviteCategoryIdentifier actions:notificationActions intentIdentifiers:#[] options:UNNotificationCategoryOptionCustomDismissAction];
NSSet *categories = [NSSet setWithObject:inviteCategory];
// registration
[center setNotificationCategories:categories];
#endif
}
else if([[[UIDevice currentDevice] systemVersion] floatValue] > 8.0f){
// create actions
UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc] init];
acceptAction.identifier = #"com.inviteapp.yes";
acceptAction.title = #"Accept";
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
acceptAction.destructive = NO;
acceptAction.authenticationRequired = NO; //If YES requies passcode, but does not unlock the device
UIMutableUserNotificationAction *declineAction = [[UIMutableUserNotificationAction alloc] init];
declineAction.identifier = #"com.inviteapp.no";
acceptAction.title = #"Decline";
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
declineAction.destructive = YES;
acceptAction.authenticationRequired = NO;
UIMutableUserNotificationAction *snoozeAction = [[UIMutableUserNotificationAction alloc] init];
snoozeAction.identifier = #"com.inviteapp.snooze";
acceptAction.title = #"Snooze";
snoozeAction.activationMode = UIUserNotificationActivationModeBackground;
snoozeAction.destructive = YES;
snoozeAction.authenticationRequired = NO;
// create a category
UIMutableUserNotificationCategory *inviteCategory = [[UIMutableUserNotificationCategory alloc] init];
inviteCategory.identifier = CYLInviteCategoryIdentifier;
NSArray *notificationActions = #[ acceptAction, declineAction, snoozeAction ];
[inviteCategory setActions:notificationActions forContext:UIUserNotificationActionContextDefault];
[inviteCategory setActions:notificationActions forContext:UIUserNotificationActionContextMinimal];
// registration
NSSet *categories = [NSSet setWithObject:inviteCategory];
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
/// 2. request authorization for localNotification
[self registerNotificationSettingsCompletionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error) {
NSLog(#"request authorization succeeded!");
}
}];
if([[[UIDevice currentDevice] systemVersion] floatValue] > 10.0f){
#if XCODE_VERSION_GREATER_THAN_OR_EQUAL_TO_8
[self localNotificationForiOS10:reminderDate];
#endif
} else {
[self localNotificationBelowiOS10: reminderDate];
}
}
- (void)registerNotificationSettingsCompletionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler; {
/// 2. request authorization for localNotification
if([[[UIDevice currentDevice] systemVersion] floatValue] > 10.0f){
#if XCODE_VERSION_GREATER_THAN_OR_EQUAL_TO_8
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
completionHandler:completionHandler];
#endif
} else if([[[UIDevice currentDevice] systemVersion] floatValue] > 8.0f){
UIUserNotificationSettings *userNotificationSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge)
categories:nil];
UIApplication *application = [UIApplication sharedApplication];
[application registerUserNotificationSettings:userNotificationSettings];
}
}
for setting multiple notifications:
iOS 10, add different requestWithIdentifier
pragma mark- Locanotification more than iOS 10
-(void) localNotificationForiOS10:(NSDate *) _reminderDate{
_eventReminderDate = _reminderDate;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond|NSCalendarUnitTimeZone fromDate:_reminderDate];
NSLog(#"NSDateComponents %#",components);
UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
objNotificationContent.title = [NSString localizedUserNotificationStringForKey:_eventname arguments:nil];
objNotificationContent.body = [NSString localizedUserNotificationStringForKey:#"You have event reminder"
arguments:nil];
objNotificationContent.sound = [UNNotificationSound defaultSound];
/// 4. update application icon badge number
objNotificationContent.badge = #([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:#"eventdate"
content:objNotificationContent trigger:trigger];
/// 3. schedule localNotification
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(#"Local Notification succeeded");
}
else {
NSLog(#"Local Notification failed");
}
}];
}
for setting multiple notifications below iOS 10, add different userinfo
pragma mark- Locanotification less than iOS 10
-(void) localNotificationBelowiOS10:(NSDate *) _reminderDate{
_eventReminderDate = _reminderDate;
NSLog(#"dateInLocalTimezone %#",_eventReminderDate);
/// 3. schedule localNotification
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = _eventReminderDate ;
localNotification.alertTitle = _eventname;
localNotification.alertBody = #"You have Event Name";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.repeatInterval = 0;
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
NSDictionary *info = [NSDictionary dictionaryWithObject:_eventname forKey:_eventname];
localNotification.userInfo = info;
NSLog(#"info ---- %#",info);
NSLog(#"notification userInfo gets name : %#",[info objectForKey:_eventname]);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
pragma mark- Delete Perticulater Local Notification
-(IBAction)deleteReminder:(id)sender{
UIButton *senderButton = (UIButton *)sender;
_selectedRow = senderButton.tag;
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:senderButton.tag inSection:0]; // if section is 0
ReminderCell * cell = (ReminderCell*)[_tableView cellForRowAtIndexPath:indexPath];
_eventname = [[_eventArray objectAtIndex:indexPath.row] objectForKey:#"event_name"];
_eventdate = [[_eventArray objectAtIndex:indexPath.row] objectForKey:#"event_date"];
_eventtime = [[_eventArray objectAtIndex:indexPath.row] objectForKey:#"event_st"];
if([[[UIDevice currentDevice] systemVersion] floatValue] > 10.0f){
#if XCODE_VERSION_GREATER_THAN_OR_EQUAL_TO_8
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
// remove all local notification:
[center removePendingNotificationRequestsWithIdentifiers:#[_eventname]];
#endif
} else {
NSLog(#"Delete notification below ios 10");
UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++)
{
UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
NSDictionary *userInfoCurrent = oneEvent.userInfo;
NSString *ename=[NSString stringWithFormat:#"%#",[userInfoCurrent valueForKey:_eventname]];
if ([ename isEqualToString:_eventname])
{
//Cancelling local notification
[app cancelLocalNotification:oneEvent];
break;
}
}
}
}