I'm having issues when trying to schedule a UILocalNotification using the following code:
- (IBAction) createNotification {
//Just to verify button called the method
NSLog(#"createNotification");
NSString *dateString = dateTextField.text;
NSString *textString = textTextField.text;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM-dd-yyyy HH:mm"];
[formatter setTimeZone: [NSTimeZone defaultTimeZone]];
NSDate *alertTime = [formatter dateFromString:dateString];
UIApplication *app = [UIApplication sharedApplication];
UILocalNotification *notification = [[[UILocalNotification alloc] init] autorelease];
if(notification){
notification.fireDate = alertTime;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.repeatInterval = 0;
notification.alertBody = textString;
[app scheduleLocalNotification:notification];
NSLog(#"%#", dateString);
}
}
The code is being called correctly when I press the button and I'm passing in the following date string:
02-12-2012 19:01
I've also tried
02/12/2012 19:01
to no avail. (I change the time accordingly depending on the time of testing e.g. 21:06)
Can someone please explain why the local notification isn't displaying?
Thanks in advance,
Jack
Local notifications are delivered, but do not display (i.e., no badges, no sounds, no alerts) when the app is running and in the foreground. But the application:didReceiveLocalNotification: method of your app delegate is called, if you need to react to a local notification in some way.
See the UILocalNotification class reference for details.
Related
When I set [NSCalendar +autoupdatingCurrentCalendar] as the repeat calendar of UILocalNotification, then call [UIApplication -scheduleLocalNotification:] with the UILocalNotification, the local notification don't get scheduled!
is this a bug of iOS 4.3?
this is the code:
UILocalNotification *l = [[UILocalNotification alloc] init];
l.fireDate = [NSDate dateWithTimeIntervalSinceNow:30];
l.alertBody = [NSString stringWithFormat:#"alert time :%#,time zone %#",l.fireDate,l.timeZone];
l.alertAction = #"OK";
l.hasAction = YES;
l.repeatInterval = NSDayCalendarUnit;
l.repeatCalendar = [NSCalendar autoupdatingCurrentCalendar];
[application scheduleLocalNotification:l];
NSLog("all local notifs: %#", [[UIApplication sharedApplication] scheduledLocalNotifications]) //empty array
I have a view controller which contains a field for user to enter date value.In contrast I have a field called "Remind Before Days" for the user to select when the notification should fire.If the remind before day is same day,then notification is set to fire on the date,but when the remind day is before 1 day,then notification should fire before one day the date set(specified).For this I have written a method called -(void)setNotification and here is the implementation code:
- (void)setNotification
{
//Set notification after confirmation of saved data
Class cls = NSClassFromString(#"UILocalNotification");
UILocalNotification *notif = [[cls alloc] init];
if (cls != nil)
{
textField = [self.fields objectAtIndex:3];
if (textField.text == #"Same Day")
{
notif.fireDate = [datePicker date];
notif.timeZone = [NSTimeZone defaultTimeZone];
}
else if(textField.text == #"1 Day")
{
NSDate *now = [datePicker date];
// set up date components
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:now];
[components setDay:-1];
// create a calendar to form date
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDate *newDate2 = [gregorian dateByAddingComponents:components toDate:now options:0];
notif.fireDate = newDate2;
notif.timeZone = [NSTimeZone defaultTimeZone];
}
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = textView.text;
notif.alertAction = #"View";
notif.soundName = #"lazy_afternoon.mp3";
notif.applicationIconBadgeNumber = 1;
textField = [self.fields objectAtIndex:1];
NSDictionary *userDict = [NSDictionary dictionaryWithObject:self.textField.text forKey:kReminder];
notif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
[notif release];
}
}
Now as we are all aware that when the notification gets fired,the user clicks view.Then we show an alert,the implementation code is written in appDelegate.Here it is:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// For The Purpose Of Notification.
Class cls = NSClassFromString(#"UILocalNotification");
if (cls)
{
UILocalNotification *notification = [launchOptions objectForKey:
UIApplicationLaunchOptionsLocalNotificationKey];
if (notification)
{
NSString *reminderText = [notification.userInfo objectForKey:kReminder];
[self.viewController showReminder:reminderText];
}
}
application.applicationIconBadgeNumber = 0;
}
Now after local notification is received,we do the following i.e.:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
application.applicationIconBadgeNumber = 0;
NSString *reminderText = [notification.userInfo objectForKey:kReminder];
[self.viewController showReminder:reminderText];
}
Now I have set the -(void)setNotification action to right navigation right bar button item titled "Save" as follows:
-(IBAction)save:(id)sender
{
[self setNotification];
}
When I don't specify any condition for fire date i.e. simply assign as :
notif.fireDate = [datePicker date]; everything's fine with notification(no issues).
But when I do as the above i.e. condition for fire date,then the notification is not getting fired.Instead the alert is getting fired when I click save.Also when I quit the simulator,I could see some thread problem.I don't understand what's wrong with the code (implementation).I have gone through several links,also the apple documentation of UILocalNotification.Couldn't find out any property or method to set fire Date according to conditions.
I found out a method "repeatTimeInterval" which is relavant and applicable when a notification must be repeated weekly,yearly etc..which doesn't suit the requirement that the "date to be fired is this when the remind days in textField is this"
Can any one please guide me right,
Thanks all in advance :)
I believe if you check this link out you will find out. But from what I have seen the code you have provide is from this site anyway.
http://useyourloaf.com/blog/2010/7/31/adding-local-notifications-with-ios-4.html
I know I arrived a little late, but for me, the error on your code is here:
if (textField.text == #"Same Day")
Because you can't compare NSStrings using the operator ==. I think that if you use isEqualToString:(NSString*) it will work properly. It would be great if you could edit your original post and fix the code, so people looking for info about local notifications won't run into the same problem.
I wrote an app that allows the user to enter data in a UITextField, and one of them allows them to enter in a specific date. I'm trying to have an alert appear in the iPhones Notification Center when the date is 15 hours away, even when the app is not running at all.
EDIT: New code-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMdd"];
NSDate *eventDate=[dateFormatter dateFromString:eventDateField.text];
localNotif.fireDate = [eventDate dateByAddingTimeInterval:-15*60*60];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = #"Event Tomorrow!";
localNotif.alertAction = #"Show me";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 0;
[[UIApplication sharedApplication]presentLocalNotificationNow:localNotif];
}
Youre trying to send the message dateByAddingTimeInterval: to whom? Nobody. You need a receiver for the message, an object that can then run the method.
[[NSDate date] dateByAddingTimeInterval: -20*60];
(NSDate date is the current date and time).
Store the date obtained from the text field in a NSDate object, eventDate. You will want to set the date with time also. The reason you are getting that error is that dateByAddingTimeInterval: should be called on an NSDate object and is not an identifier in itself. Set the fireDate of your local notification as
localNotif.fireDate=[eventDate dateByAddingTimeInterval:-15*60*60];
This will return a date which is 15 hours before the event.
EDIT: You need to create an NSDateFormatter object and set its format to how it is stored in meetingDateField. Then use the dateFromString: to get the NSDate from the text field.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm'/'dd'/'yyyy"];
NSDate *eventDate=[dateFormatter dateFromString:meetingDateField.text];
In order to call [-dateByAddingTimeInterval:], you must have an NSDate object. In your code above, you don't. It should look something like:
NSDate* now = [NSDate date];
localNotif.fireDate = [now dateByAddingTimeInterval:20*60];
I am currently scheduling local notifications to appear once per day at 6PM if a user has not already opened the app that day. If the user has already loaded the application, then I want to cancel the notification for that day and schedule a new one for tomorrow at 6PM. The notification displays properly, however, when I try to iterate of the list of scheduled notifications (this is not the only local notification I have in the application), the [[UIApplication sharedApplication] scheduledLocalNotifications] array is always empty. Below is the code snippet that is giving me trouble:
// See if we need to create a local notification to tell the user that they can receive a daily reward
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications]; // <- This is always empty
// Iterate over all the pending notifications
for( int iter = 0; iter < [notifications count]; iter++ )
{
UILocalNotification* localNotification = [notifications objectAtIndex:iter];
if( [[localNotification.userInfo objectForKey:#"source"] isEqualToString:#"dailyReminder"] )
[[UIApplication sharedApplication] cancelLocalNotification:localNotification];
}
NSCalendar* calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *nowComponents = [calendar components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSSecondCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:serverDate];
int hour = [nowComponents hour];
int minute = [nowComponents minute];
int second = [nowComponents second];
int hoursToAdd = 18 - hour;
NSDateComponents *comps = [[[NSDateComponents alloc] init] autorelease];
[comps setDay:1];
[comps setHour:hoursToAdd];
[comps setMinute:-minute];
[comps setSecond:-second];
NSDate *tomorrow6PM = [calendar dateByAddingComponents:comps
toDate:serverDate
options:0];
NSMutableDictionary* userInfo = [NSMutableDictionary dictionary];
[userInfo setObject:#"dailyReminder" forKey:#"source"];
scheduleNotification(tomorrow6PM, NSLocalizedString(#"Come Back!", #"daily reminder notification message"), NSLocalizedString(#"Launch", #"daily reminder notification button text"), [UIApplication sharedApplication].applicationIconBadgeNumber+1, userInfo);
the scheduleNotification function is straightforward and just constructs a local notification:
void scheduleNotification(NSDate* fireIn, NSString* bodyText, NSString* alertText, NSUInteger badgeCount, NSMutableDictionary* userInfo)
{
static int appCount = 0;
appCount += 1;
if(!isLocalNotificationEnabled())
return;
Class localNotificationClass = NSClassFromString(#"UILocalNotification");
UILocalNotification* localNotification = [[localNotificationClass alloc] init];
if(!localNotification)
return;
localNotification.fireDate = fireIn;
localNotification.timeZone = [NSTimeZone systemTimeZone];
localNotification.alertBody = bodyText;
localNotification.alertAction = alertText;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = badgeCount;
localNotification.userInfo = userInfo;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[localNotification release];
}
I don't understand why the array of local notifications is always empty. Like I said before the notifications display at the correct time, so they are getting scheduled. Any help is appreciated.
Having similar issues right now. My guess here is that iOS does not schedule the notifications immediately but only at the end of the current run loop. I am running into these problems when setting the scheduledLocalNotifications property several times in the same run loop and changes don't seem to be updated accordingly. I think I will just keep a copy of the local notifications array myself and only set scheduledLocalNotifications and never read it.
localNotification.fireDate = fireIn;
in this line check wheather "fireIn" is object of NSDate or NSString.
If it's NSString convert it into NSDate object with help of NSDateformatter and then assing it to localNotification fireDate.
I was facing same problem previously and resolved it with above mentioned steps.
if the schedule has invalid fire date, it will not get scheduled and result empty array returned, because there never has a valid one schedule, try to print out your localNotification like below, you may find out the problem.
NSLog(#"Notification--->: %#", localNotification);
I am trying to fire a method once a day at a given time. I've tried a few things but I can't really make it work. any advice would be appreciated. Also, it would be ideal if it would fire regardless of if the app is open or not. Is this possible?
UILocalNotification will let you fire a notification (but not a method) when your app is running in the background, or will call a delegate method you implement (application:didReceiveLocalNotification:) if the app is running in the foreground, or will call a method you must implement (application:didFinishLaunchingWithOptions:) when the user responds to the alert. Other than this, you will not be able to call a method when the app is not in the foreground, you will only be able to fire the the notification (which can display the badge, play a sound, etc).
By the way, consider filing a bug report with apple if this is a feature you want. I would like the ability to run methods in the background based on local notifications, without waiting for the user to respond first.
See Apple's example code:
- (void)scheduleNotificationWithItem:(ToDoItem *)item interval:(int)minutesBefore {
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:item.day];
[dateComps setMonth:item.month];
[dateComps setYear:item.year];
[dateComps setHour:item.hour];
[dateComps setMinute:item.minute];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
[dateComps release];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = [itemDate addTimeInterval:-(minutesBefore*60)];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(#"%# in %i minutes.", nil),
item.eventName, minutesBefore];
localNotif.alertAction = NSLocalizedString(#"View Details", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:item.eventName forKey:ToDoItemKey];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}