i used the local notification and schedule the fire date but when the app is in background and i open the notification tray to see the notification then the local notification is fire automatically but the fire date is remaining..is there any solution to solve that problem
This sounds like you have two issues. First, the local notification has been created with a fire date set in the past - that's why its appearing as soon as you open the app.
Secondly, you may be setting the notification's repeatInterval to a non-zero value, which will cause it to come up more than once.
See the below code for setting a local notification to fire at 3pm:
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = #"This is a test alert";
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setHour: 15];
[comps setMinute: 0];
[comps setSecond: 0];
NSDate *threePM = [currentCalendar dateFromComponents:comps];
// Test if the current time is after three or not:
if(threePM != [threePM earlierDate: [NSDate date]])
{
comps = [[NSDateComponents alloc] init];
[comps setDay: 1];
threePM = [currentCalendar dateByAddingComponents: comps toDate: threePM options: 0];
}
localNotification.fireDate = threePM;
localNotification.repeatInterval = 0;
[[UIApplication sharedApplication] scheduleLocalNotification: localNotification];
Related
I am trying to get my app working with local notifications. But I can't get my head arround. I'm looking after the problem for days. I have in my core database an entity Favorites (all my favorite artists) and an entity Artists (artist his detail information.
I have a button to set the local notification on. When I press the button, I do the following.
-(void)addLocalNotifications{
GenkonStageDataModel *model = [[GenkonStageDataModel alloc]init];
NSMutableArray *allFavorites = [model getAllFavorites];
NSLog(#"allFavoriets count is %d",allFavorites.count);
UIApplication* app = [UIApplication sharedApplication];
for (int i = 0; i<allFavorites.count; i++){
Favorites *favorite = [allFavorites objectAtIndex:i];
int artId = [favorite.fav_art_id intValue];
Artists *artist = [model getArtistById:artId];
UILocalNotification* notifyAlarm = [[UILocalNotification alloc]
init];
if (notifyAlarm)
{
NSDate *datePush = [self getDateForArtist:artist];
NSLog(#"Push notification should send on: %#",datePush);
notifyAlarm.fireDate = datePush;
NSDictionary *dicNotification = [[NSDictionary alloc]initWithObjectsAndKeys:artist.art_id,#"pushKey", nil];
notifyAlarm.userInfo = dicNotification;
notifyAlarm.repeatInterval = 0;
notifyAlarm.soundName = #"Glass.aiff";
notifyAlarm.alertBody = [NSString stringWithFormat:#"%# starts in 15 minutes",artist.art_name];
[app scheduleLocalNotification:notifyAlarm];
NSLog(#"Added");
}
}
}
What this method does is the following.
1. Get all the favorites
2. Loop through the favorites and get the artists linked with that favorite by ID
3. Get the date for when the local notification should be sent
4. Set in the userInfo dictionary the artist ID (I do this for deleting the local notification when I want to)
5. Shedule the local notification.
Now all these are added (I think) because it loops correctly through the array and also always gives me the correct date and "ADDED" in my log.
But now when I change my device it's dateTime to the time that I normally should receive the local notification. I do not receive anything!!!!
I also changed my date to 2hours earlier for the correct time. Because when I was testing with an example local notification. They setted the fireDate like this.
NSDate *alertTime = [NSDate date];
This caused that the local notifcation was sent immedialty after that I clicked the button. But when I logged this I noticed that is was 2 hours before the actual time... ?
I seriously hope that anybody can help me with this problem!
Thanks in advance!
EDIT
This is how I get my fireDate
-(NSDate *)getDateForArtist:(Artists *)artist{
int day = [artist.art_day intValue];
int timeStart = [artist.art_timestart intValue];
NSString *timeStart2 = [self getTimeStamp:artist.art_timestart];
int hours = [[timeStart2 substringWithRange:NSMakeRange(0,2)]intValue];
int minutes = [[timeStart2 substringWithRange:NSMakeRange(2,2)]intValue];
int day2;
if(timeStart >=2400 ){
day = day++;
}
if(day == 1){
NSLog(#"day is 28");
day2 = 28;
}else if (day == 2){
NSLog(#"day is 29");
day2 = 29;
}else{
NSLog(#"day is 30");
day2 = 30;
}
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:day2];
[comps setMonth:06];
[comps setYear:2013];
[comps setHour:hours];
[comps setMinute:minutes];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:comps];
NSLog(#"date is %#",date);
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setMinute:-15];
NSDate *date2 = [gregorian dateByAddingComponents:offsetComponents toDate:date options:0];
NSLog(#"date -15 min %#", date2);
return date2;
}
And I get this LOG
2013-06-30 14:37:13.910 genkonstage[1633:907] date is 2013-06-30 16:50:00 +0000
2013-06-30 14:37:13.913 genkonstage[1633:907] Push notification should send on: 2013-06-30 16:35:00 +0000
From your comment (works 10 seconds ahead) it sounds like it's working fine.
When you change the device's date/time how are you doing it? forwards in time? backwards? are you altering the timezone?
Also are you scheduling notifications with a date/time that is in the past? If you specify a date that is in the past (or nil) the notification is delivered immediately.
The fire date is evaluated using the timeZone property of the UILocalNotification object, so if you do not set the timezone the fire data is considered to be GMT time. try:
notifyAlarm.timeZone = [NSTimeZone defaultTimeZone];
If you set a fire date of 09:00 and then move to a different time zone the alarm will still fire at 09:00 in the new time zone.
It was quite a bit hard to enable local notifications for my application.
And yeah, I set up my project with a local notification witch I want to schedule after the app had been closed for one week. For example if the user opens the app on saturday 8th, the local notification should appear on the next saturday the 15th, but the time should changed. For example he/she closes the app at 8pm and I don't want to disturb them at 8pm next week so I want to display every notification at 6pm or something like that.
Now you know my problem and here is my code I'm using:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar] ;
NSDateComponents *componentsForReferenceDate = [[NSDateComponents alloc] init];
//set day (saturday)
[componentsForReferenceDate setDay:26] ;
[componentsForReferenceDate setMonth:1] ;
[componentsForReferenceDate setYear:2013] ;
[componentsForReferenceDate setHour: 17] ;
[componentsForReferenceDate setMinute:30] ;
[componentsForReferenceDate setSecond:00] ;
NSDate *fireDateOfNotification = [calendar dateFromComponents: componentsForReferenceDate];
// Create the notification
UILocalNotification *notification = [[UILocalNotification alloc] init] ;
notification.fireDate = fireDateOfNotification ;
notification.timeZone = [NSTimeZone localTimeZone] ;
notification.alertBody = [NSString stringWithFormat: #"Du wirst vermisst! \nDeine App braucht dich, schreibe sie zu Ende!"] ;
notification.alertAction = #"Zurückkehren";
notification.userInfo= [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"Some information"] forKey:#"information"];
notification.repeatInterval= NSWeekCalendarUnit ;
notification.soundName = #"Appnotifisound.wav";
notification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:notification] ;
}
I know that there have to be more methods for deleting the badge and the didrecievenotification, but I let them out because there are not important for this.
With this code I managed to schedule the notification on every saturday at 5:30pm (Germany). But I wanted to schedule it only once, when the app had been closed for exactly one week. Is that somehow possible? I would be glad if someone could correct my code or give me a solution for this.
Best regards and thank you for reading this long post,
Noah
You should unschedule previous notification.
for (UILocalNotification *lNotification in [[UIApplication sharedApplication] scheduledLocalNotifications])
{
if ([[lNotification.userInfo valueForKey:#"information"] isEqualToString:#"Some information"])
{
[[UIApplication sharedApplication]cancelLocalNotification:lNotification];
break;
}
}
Set fire date by below way:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *componentsForReferenceDate = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
fromDate:[NSDate date]];
[componentsForReferenceDate setHour: 17] ;
[componentsForReferenceDate setMinute:30] ;
[componentsForReferenceDate setSecond:00] ;
NSDate *tempDate = [calendar dateFromComponents: componentsForReferenceDate];
[componentsForReferenceDate release];
NSDateComponents *comps = [[NSDateComponents alloc]init];
[comps setDay:7];
NSDate *fireDateOfNotification = [calendar dateByAddingComponents:comps
toDate:tempDate options:0]
[comps release];
The notification.repeatInterval = NSWeekCalendarUnit is causing this. use:
notification.repeatInterval = 0;
This prevent repeating (source).
Here is the Swift 2.0 adaptation
Unscheduling the current notification
for notifMe:AnyObject in UIApplication.sharedApplication().scheduledLocalNotifications!{
let title = notifMe.userInfo["information"] as? String
if title == "some information"{
UIApplication.sharedApplication().cancelLocalNotification(notifMe as! UILocalNotification)
}
}
Setting the date for the notification
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(NSCalendarUnit.Year.union(NSCalendarUnit.Month).union(NSCalendarUnit.Day),fromDate: date)
components.hour = 17
components.minute = 30
components.second = 00
let tempDate = calendar.dateFromComponents(components)!
let comps = NSDateComponents()
comps.day = 7
let fireDateOfNotification = calendar.dateByAddingComponents(comps, toDate: tempDate, options:[])
I looked at many pieces of codes but didn't get solution yet,
I simply need to get my app icon badge updated daily with some calendar (not gregorian) number of the day.
How can I do that?
I don't know how you would code it, but if you were going to submit such an app to the app store, apple wouldn't approve it. Apple's strict review guidelines can be frustrating, and like in this case, they limit functionality of your apps. Sorry :(
You obviously can't use repeating local notifications, because you want to specify an application badge number. Therefore you have to use one local notification for each day scheduled at midnight and with the appropriate badge number.
Because you can only schedule a maximum of 64 local notifications, you have to queue the notifications at each application launch.
This code isn't tested, there might be problems with daylight saving times, etc. (Works on iOS 4.2 or later, using ARC)
- (void) applicationDidBecomeActive:(UIApplication *)application {
NSUInteger startingDayAfterToday = [application.scheduledLocalNotifications count];
NSArray *localNotifications = [self localNotificationsStartingOnDayAfterToday:startingDayAfterToday];
NSArray *newScheduledNotifications = [application.scheduledLocalNotifications arrayByAddingObjectsFromArray:localNotifications];
[application setScheduledLocalNotifications:newScheduledNotifications];
}
- (NSArray *) localNotificationsStartingOnDayAfterToday:(NSUInteger)startingDayAfterToday {
NSMutableArray *localNotifications = [[NSMutableArray alloc] initWithCapacity:64 - startingDayAfterToday];
for (NSUInteger i = startingDayAfterToday; i < 64; i++) {
// Create a new local notification
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.hasAction = NO;
// Create today's midnight date
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; // Could be other calendar, too
NSDateComponents *todayDateComponents = [calendar components:(NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
NSDate *todayMidnight = [calendar dateFromComponents:todayDateComponents];
// Create the fire date
NSDateComponents *addedDaysComponents = [[NSDateComponents alloc] init];
addedDaysComponents.day = i;
NSDate *fireDate = [calendar dateByAddingComponents:addedDaysComponents toDate:todayMidnight options:0];
// Set the fire date and time zone
notification.fireDate = fireDate;
notification.timeZone = [NSTimeZone systemTimeZone];
// Set the badge number
NSDateComponents *fireDateComponents = [calendar components:NSDayCalendarUnit fromDate:fireDate];
notification.applicationIconBadgeNumber = fireDateComponents.day;
// We're done, add the notification to the array
[localNotifications addObject:notification];
}
return [localNotifications copy];
}
I can't get my local notifications to show. I am testing on the iphone. They do not show up at all and the date generated seems to be an hour before the one entered. 19 becomes 18 and so on.
How do I enable these local notifications at 7 while taking into account the user's time zone?
NSCalendar* myCalendar = [NSCalendar currentCalendar];
NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
[components setHour: 19];
[components setMinute:00];
NSDate *todayAt7 = [myCalendar dateFromComponents:components];
UILocalNotification *dailyNotification = [[UILocalNotification alloc] init];
dailyNotification.fireDate = todayAt7; // set this to 7pm
dailyNotification.timeZone = [NSTimeZone defaultTimeZone];
dailyNotification.repeatInterval = NSDayCalendarUnit;
dailyNotification.soundName = UILocalNotificationDefaultSoundName;
dailyNotification.alertBody = #"You need to enter data for today.";
The first issue is that when you are creating he components instance, you are not asking for the hour and minutes components. Also, you should use NSCalendar *myCalendar = [NSCalendar autoupdatingCurrentCalendar]; instead of currentCalendar.
Second issue, at least your not showing the code for it, but you're not actually scheduling the notification object. See [UIApplication scheduleLocalNotification:].
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);