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:[])
Related
I have schedule UILocalNotification in my application at 10:00 AM Every Day.
I have used following code for this
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar] ;
NSDateComponents *componentsForReferenceDate =
[calendar components:(NSDayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit ) fromDate:[NSDate date]];
[componentsForReferenceDate setDay:10] ;
[componentsForReferenceDate setMonth:10] ;
[componentsForReferenceDate setYear:2013] ;
NSDate *referenceDate = [calendar dateFromComponents:componentsForReferenceDate] ;
// set components for time 10:00 a.m.
NSDateComponents *componentsForFireDate =
[calendar components:(NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit| NSSecondCalendarUnit ) fromDate: referenceDate];
[componentsForFireDate setHour:10] ;
[componentsForFireDate setMinute:0] ;
[componentsForFireDate setSecond:0] ;
NSDate *fireDateOfNotification = [calendar dateFromComponents: componentsForFireDate];
// Create the notification
UILocalNotification *notification = [[UILocalNotification alloc] init] ;
notification.fireDate = fireDateOfNotification ;
notification.timeZone = [NSTimeZone localTimeZone] ;
notification.alertBody = [NSString stringWithFormat: #"Good Morning! Have a great day!"] ;
notification.alertAction = #"go back";
notification.userInfo= [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"Some information"] forKey:#"information"];
notification.repeatInterval = NSDayCalendarUnit ;
notification.soundName = UILocalNotificationDefaultSoundName;
notification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:notification] ;
It's working very good.
but now I want to schedule UILocalNotification at Every other day and every third day.
so how to do this?
You can not do customization of repeatTimeInterval of UILocalNotification.. there are many question as same like yours and also some days ago I had same question but i can not find any solution so please better is stop fight with it.
You must need to use repeat time interval from
Calendar Units
Specify calendrical units such as day and month.
enum {
NSEraCalendarUnit = kCFCalendarUnitEra,
NSYearCalendarUnit = kCFCalendarUnitYear,
NSMonthCalendarUnit = kCFCalendarUnitMonth,
NSDayCalendarUnit = kCFCalendarUnitDay,
NSHourCalendarUnit = kCFCalendarUnitHour,
NSMinuteCalendarUnit = kCFCalendarUnitMinute,
NSSecondCalendarUnit = kCFCalendarUnitSecond,
NSWeekCalendarUnit = kCFCalendarUnitWeek,
NSWeekdayCalendarUnit = kCFCalendarUnitWeekday,
NSWeekdayOrdinalCalendarUnit = kCFCalendarUnitWeekdayOrdinal,
NSQuarterCalendarUnit = kCFCalendarUnitQuarter,
NSWeekOfMonthCalendarUnit = kCFCalendarUnitWeekOfMonth,
NSWeekOfYearCalendarUnit = kCFCalendarUnitWeekOfYear,
NSYearForWeekOfYearCalendarUnit = kCFCalendarUnitYearForWeekOfYear
NSCalendarCalendarUnit = (1 << 20),
NSTimeZoneCalendarUnit = (1 << 21),
};
typedef NSUInteger NSCalendarUnit;
Above you can found from Apple's documentation. also read this question...
How to set Local Notification repeat interval to custom time interval?
For more information , you only scheduled local notification maximum 64, so be careful if may be you have planing in you mind that, you want to create multiple notification for do custom repeat time intervals..
You can't do this simply with repeatInterval, because only the following intervals are available.
One of the solutions I can think of would be to set separate notifications for each day (without repeatInterval). But by doing it in this way you can stumble on 64 notifications limit.
I'm working with local notification. I got the notifications working. But I'm struggling with setting the correct date.
Let me first sketch the situation. I am making a festival app. This festival is on the 28-29-30 JUNE. Every artist object has an art_day. This can be 1 - 2 or 3.
1 --> 28 JUNE
2 --> 29 JUNE
3 --> 30 JUNE
I want a local notification 15 min before the start time of the artist. So this is how I'm making my fireDate of the notification.
-(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];
//in my db timeStart looks like 1530 --> 15h30 (I know bad db structure!!!)
int day2;
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];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"GMT"];
[comps setTimeZone:timeZone];
[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;
}
This is how I create my notification
UIApplication* app = [UIApplication sharedApplication];
UILocalNotification* notifyAlarm = [[UILocalNotification alloc]
init];
if (notifyAlarm)
{
NSDate *datePush = [self getDateForArtist:artist];
NSLog(#"artist plays on: %# on hour %#",artist.art_day,artist.art_timestart);
NSLog(#"Push notification should send on: %#",datePush);
notifyAlarm.fireDate = datePush;
NSDictionary *dicNotification = [[NSDictionary alloc]initWithObjectsAndKeys:artist.art_id,#"pushKey", nil];
notifyAlarm.userInfo = dicNotification;
notifyAlarm.timeZone = [NSTimeZone defaultTimeZone];
notifyAlarm.repeatInterval = 0;
notifyAlarm.soundName = #"Glass.aiff";
notifyAlarm.alertBody = [NSString stringWithFormat:#"%# starts in 15 minutes",artist.art_name];
[app scheduleLocalNotification:notifyAlarm];
NSLog(#"Added");
}
But for some reason I don't get any push notification. Or I think that the date is not correct.
This is what I get from my logs
2013-06-29 15:37:17.801 genkonstage[14120:907] artist plays on day: 2 on hour 2020
2013-06-29 15:37:17.803 genkonstage[14120:907] Push notification should send on: 2013-06-29 20:05:00 +0000
Can anybody help me with this?
I am in the final stages of development for an iPhone Alarm App
The alarm works through notification centre.
Work well for short time delays (say 2 hours)
Does not work in the morning (Long time delay 8 hours)
Also it seems to work fine on phones that do not have internet access?
Could there be some kind of automatic time updating/syncing that is disturbing alarm function?
Is the 8 hour+ time delayed neutralising the notificaiton?
Does the app need to be in the foreground?
So the alarm works for short time delays, but not in the morning (When it is meant to!)
We are due to submit update to Apple very soon!
Thank you Kindly,
Henry (Aus.)
-(void)addLocalNotification:(myAlarmData *)ma WeekDay:(int)mweekday
{
UILocalNotification *noti = [[UILocalNotification alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *now = [NSDate date];
NSDateComponents *dcom = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit |NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit) fromDate:now];
[dcom setWeekday:mweekday];
[dcom setHour:ma.mHour];
[dcom setMinute:ma.mMinute];
[dcom setSecond:0];
NSDate *fireDate = [gregorian dateFromComponents:dcom];
noti.fireDate = fireDate;
noti.timeZone = [NSTimeZone localTimeZone];
noti.alertBody = [NSString stringWithFormat:#"Wake up %#!", [GlobalData gSettings].name];
noti.soundName = [NSString stringWithFormat:#"%#.caf", ma.soundName];
noti.alertAction = #"OK";
noti.repeatInterval = NSWeekCalendarUnit;
noti.userInfo = [[[NSDictionary alloc] initWithObjectsAndKeys:
ma.mid, #"mid",
[NSString stringWithFormat:#"%d", mweekday], #"day",
ma.soundName, #"sound",
[NSString stringWithFormat:#"%d", ma.snooze], #"snooze",
ma.title, #"title",
#"Close", #"action",
#"real", #"more",
nil] autorelease];
[[UIApplication sharedApplication] scheduleLocalNotification:noti];
[noti release];
[gregorian release];
}
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];
I want to set an alarm on a particular day. I don't understand how to set the value of kCFCalendarUnitWeekday. Here is my code:
NSDateComponents *components = [[NSDateComponents alloc] init];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = selected;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.repeatCalendar = [NSCalendar currentCalendar];
if (isSun) {
[components setWeekday:1];
[localNotif setRepeatInterval:(NSInteger)components];
}
if (isMon) {
[components setWeekday:2];
[localNotif setRepeatInterval:(NSInteger)components];
}
Thank you.
Ok here is some code to get you in the right direction:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit|NSYearCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:[NSDate date]];
// this will set the weekday to sunday
[components setWeekday:1];
// this is a new date on sunday
NSDate * newDate = [gregorian dateFromComponents:components];
You still have to find out whether the newDate is in the past, so it won't fire.
You actually have your code ready:
// ... init code ...
// *** this the important date ***
localNotif.fireDate = dateOnASunday;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.repeatCalendar = NSWeekCalendarUnit;
... // add body etc. ...
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
Create a method around this snippet and pass the date with a parameter so you can reuse it. You only have to put in a date which should be the first fire date and it'll repeat every week. You just have to pass in a date on a Sunday or Wednesday.
You set a repeat interval like this:
// repeats notification on a weekly basis
localNotif.repeatCalendar = NSWeekCalendarUnit;
The repeatCalender property is of type NSCalendarUnit which is an enum.