I am new to iOS. I am making an alarm application and I want to implement the repeat functionality. I search a lot and didn't understand much how to do this. I know it is done by notification method. I am stuck with it . Please anyone tell me the solution. Here is my code when user save the alarm.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
NSLog(#"dateformater %#",dateFormatter);
dateFormatter.timeStyle = NSDateFormatterShortStyle;
NSString * dateTimeString = [dateFormatter stringFromDate:timePicker.date];
NSLog(#"date time string %#",dateTimeString);
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:NSLocaleIdentifier]];
//[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
datesArray = #[[dateFormatter stringFromDate:self.timePicker.date]];
NSLog(#"dates array is %#",datesArray);
[datesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
NSArray * repeatDays = [repeatResult componentsSeparatedByString:#","];
for (NSString * days in repeatDays)
{
if ([days isEqualToString:#"Sun"])
{
[self getDateOfSpecificDay:1];
}
if ([days isEqualToString:#"Mon"])
{
[self getDateOfSpecificDay:2];
}
if ([days isEqualToString:#"Tue"])
{
[self getDateOfSpecificDay:3];
}
if ([days isEqualToString:#"Wed"])
{
[self getDateOfSpecificDay:4];
}
if ([days isEqualToString:#"Thu"])
{
[self getDateOfSpecificDay:5];
}
if ([days isEqualToString:#"Fri"])
{
[self getDateOfSpecificDay:6];
}
if ([days isEqualToString:#"Sat"])
{
[self getDateOfSpecificDay:7];
}
}
}];
AlarmObject * alarm = [[AlarmObject alloc] init];
alarm.repeatData = repeatResult;
alarm.clockDate = dateTimeString;
[self.delegate alarmSetting:alarm];
[self scheduleLocalNotificationWithDate:timePicker.date];
[self.navigationController popViewControllerAnimated:YES];
and here is my scheduledLocalNotification mehtod
-(void) scheduleLocalNotificationWithDate:(NSDate *)fireDate
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.alertBody = #"Time to wake Up";
localNotif.alertAction = #"Show me";
localNotif.soundName = #"Tick-tock-sound.mp3";
localNotif.applicationIconBadgeNumber = 1;
localNotif.repeatInterval = NSCalendarUnitWeekOfYear;
NSLog(#"%#",[NSDate date]);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];`
I'm stuck with it from past 4 days. I know my question is duplicate but I am not sure how implement that logic. Thanks in advance.
Change the
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
to
dateFormatter.timeZone = [NSTimeZone localTimeZone];
and check out this tutorial for repeat fucntionailty.
Related
Sometimes local notification is generating multiple notifications for a single event number is 10. However I'm not getting in testing it's a rare case.
Is there any issue with a particular OS version ??
code is here
-(void)startLocalNotification:(NSDate *)notificationDate startTimeOfShift:(NSString *)startTime {
NSLog(#"startLocalNotification");
NSDateFormatter *newDateFormatter =[[NSDateFormatter alloc]init];
[newDateFormatter setDateFormat:#"dd/MM/yyyy"];
NSString *startDateStr =[newDateFormatter stringFromDate:notificationDate];
NSString *scheduleDateTimeString =[NSString stringWithFormat:#"%# %#:00.000",startDateStr,startTime];
NSLog(#"scheduleDateTimeString :%#",scheduleDateTimeString);
NSDate *setFireDate,*notificationScheduledDateAndTime,*currentDate;
[newDateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss.SSS"];
notificationScheduledDateAndTime =[newDateFormatter dateFromString:scheduleDateTimeString];
setFireDate =[notificationScheduledDateAndTime dateByAddingTimeInterval:-60*15];
currentDate =[NSDate date];
// NSTimeInterval distanceBetweenDates = [notificationScheduledDateAndTime timeIntervalSinceDate:[NSDate date]];
// NSLog(#"distanceBetweenDates :%f",distanceBetweenDates);
NSLog(#"Current Date :%# setFireDate :%#",currentDate,setFireDate);
if(counts > 15){
doNotShowNotificationAlert = NO;
}
switch ([currentDate compare:setFireDate]){
case NSOrderedAscending: {
NSLog(#"NSOrderedAscending");
}
case NSOrderedSame: {
NSLog(#"NSOrderedSame");
if(doNotShowNotificationAlert == NO){
notification = [[UILocalNotification alloc] init];
notification.fireDate = setFireDate;
NSLog(#"setFireDate :%#",setFireDate);
notification.alertBody = #"Shift Start Alert!! 15 mins to go.";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"100" forKey:#"notificationID"];
notification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
NSLog(#"info Dict :%#",infoDict);
doNotShowNotificationAlert = YES;
}
break;
}
case NSOrderedDescending: {
NSLog(#"NSOrderedDescending");
break;
}
}
}
Everything works fine with the following code if it is not change the day. But when change the day puts the badge 2 instead to put 1.
You know why this happens?
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = startDate;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = [NSString stringWithFormat:#"%# '%#'.", NSLocalizedString (#"Tiene tareas pendientes para realizar en su acuario", ""), descripcionAcuario];
localNotification.alertAction = descripcionTextField.text;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
NSDictionary *inventory = #{
#"AcuarioID" : [NSNumber numberWithInt: acuarioSeleccionadoID],
#"TareaID" : [NSNumber numberWithInt: tareaSeleccionada],
};
localNotification.userInfo= inventory;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"YYYY-MM-dd HH:mm:ss"];
NSString *alarmTimeStr = [[NSString alloc]init];
alarmTimeStr = [NSString stringWithFormat:#"%#",alarmTimeTextField.text];
NSDate *pickerdate = dateTimePicker.date;
[[NSCalendar currentCalendar] rangeOfUnit:NSMinuteCalendarUnit
startDate:&pickerdate
interval:NULL
forDate:pickerdate];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
pickerDate1 = pickerdate;
finaldate =pickerDate1;
// ** Local notification Assignment **
localNotification = [[UILocalNotification alloc] init];
if (localNotification == nil)
return;
localNotification.fireDate = pickerDate1;
localNotification.alertBody = alarmNameTextField.text;
localNotification.alertAction = #"OK";
localNotification.soundName = [NSString stringWithFormat:#"%#.mp3",alarmTonesTextField.text];
localNotification.timeZone = [NSTimeZone systemTimeZone];
[localNotification setHasAction:YES];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[self setalarm];
-(void)setalarm
{
if ([sunValue isEqualToString:#"1"])
{
finaldate =pickerDate1;
[self getDateOfSpecificDay:1];
[self setweek];
}
if ([monValue isEqualToString:#"1"])
{
finaldate =pickerDate1;
[self getDateOfSpecificDay:2];
[self setweek];
}
if ([tueValue isEqualToString:#"1"])
{
finaldate =pickerDate1;
[self getDateOfSpecificDay:3];
[self setweek];
}
if ([wedValue isEqualToString:#"1"])
{
finaldate =pickerDate1;
[self getDateOfSpecificDay:4];
[self setweek];
}
if ([thuValue isEqualToString:#"1"])
{
finaldate =pickerDate1;
[self getDateOfSpecificDay:5];
[self setweek];
}
if ([friValue isEqualToString:#"1"])
{
finaldate =pickerDate1;
[self getDateOfSpecificDay:6];
[self setweek];
}
if ([satValue isEqualToString:#"1"])
{
finaldate =pickerDate1;
[self getDateOfSpecificDay:7];
[self setweek];
}
alarmArray = [[DBManager sharedDatabase] getAlarmsDetail];
if ([alarmArray count] != 0)
{
[self showAllAlarmsInAlarmView];
}
if ([alarmArray count]==0)
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
}
-(void)setweek
{
#try
{
NSDateFormatter *formatterdate=[[NSDateFormatter alloc]init];
[formatterdate setDateFormat:#"YYYY-MM-dd"];
NSDateFormatter *formattertime =[[NSDateFormatter alloc]init];
[formattertime setDateFormat:#"HH:mm:ss"];
NSString * stringdate = [NSString stringWithFormat:#"%#",resultDate];
NSString *stringdate123 =[stringdate substringToIndex:10];
NSString *stringtime =[dateFormatter stringFromDate:pickerDate1];
NSString * stringtime123 =[stringtime substringFromIndex:11];
NSString * stringdate1234=[stringdate123 stringByAppendingString:#" "];
NSString * stringdate12345=[stringdate1234 stringByAppendingString:stringtime123];
finaldate =[dateFormatter dateFromString:stringdate12345];
localNotification = [[UILocalNotification alloc] init];
if (localNotification == nil)
return;
localNotification.fireDate = finaldate;
localNotification.alertBody = alarmNameTextField.text;
localNotification.repeatInterval =NSWeekCalendarUnit;
localNotification.alertAction = #"OK";
localNotification.soundName = [NSString stringWithFormat:#"%#.mp3",alarmTonesTextField.text];//#"Jai Hanuman.mp3";
localNotification.timeZone = [NSTimeZone systemTimeZone];
[localNotification setHasAction:YES];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
#catch (NSException *exception)
{
[[saveClass shared_class] writeStringToFile:#"alarmViewController" andfunctionname:#"saveAlarmAndSetNotification" andexception:(NSString*)exception];
}
#finally
{}
}
-(NSDate *) getDateOfSpecificDay:(NSInteger ) day /// here day will be 1 or 2.. or 7
{
NSInteger desiredWeekday = day;
NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSWeekdayCalendarUnit];
NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:finaldate];
NSLog(#"%#",[NSDate date]);
NSInteger currentWeekday = dateComponents.weekday;
if (desiredWeekday == currentWeekday)
{
differenceDays = 7;
daysComponents = [[NSDateComponents alloc] init];
}
else
{
differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
daysComponents = [[NSDateComponents alloc] init];
}
daysComponents.day = differenceDays;
resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:finaldate options:0];
return resultDate;
}
I have an array of dates
NSArray *datesArray=[NSArray arrayWithObjects: #"2014-09-14 00:00:00",#"2014-08-21 07:12:36",#"2014-08-14 00:00:00",#"2014-07-14 00:00:00",#"2014-06-14 00:00:00",#"2015-01-01 10:00:00",#"2014-06-14 00:00:00",#"2014-05-14 11:24:15", nil];
now i want to fire one day before the date available in array
How to implement it?
I was trying this
NSDateFormatter *Formatter1 = [[NSDateFormatter alloc] init];
[Formatter1 setLocale:[[NSLocale alloc] initWithLocaleIdentifier:NSLocaleIdentifier]];
[Formatter1 setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[Formatter1 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
NSDate *date1 =[NSDate date];
NSString *string =[Formatter1 stringFromDate:date1];
NSLog(#"sring %#",string);
NSDate *todaydate =[Formatter1 dateFromString:string];
NSLog(#"2day date is %#",todaydate);
for (int i=0;i<datesArray.count;i++)
{
NSDate *_date =[Formatter1 dateFromString:[datesArray objectAtIndex:i ]];
NSLog(#"date is %#",_date);
if(_date == todaydate){
localNotif.fireDate = _date;
localNotif.alertBody = #"festival";
localNotif.alertAction=#"Show me";
localNotif.applicationIconBadgeNumber = 1;
localNotif.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
You can subtract a day by using the NSCalendar functions, specifically dateByAddingComponents
NSArray *datesArray = #[#"2014-09-14 00:00:00",#"2014-08-21 07:12:36",#"2014-08-14 00:00:00",#"2014-07-14 00:00:00",#"2014-06-14 00:00:00",#"2015-01-01 10:00:00",#"2014-06-14 00:00:00",#"2014-05-14 11:24:15"];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:-1];
NSDateFormatter *Formatter1 = [[NSDateFormatter alloc] init];
[Formatter1 setLocale:[[NSLocale alloc] initWithLocaleIdentifier:NSLocaleIdentifier]];
[Formatter1 setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[Formatter1 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[datesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [calendar dateByAddingComponents:dateComponents toDate:[Formatter1 dateFromString:obj] options:0];
localNotif.alertBody = #"festival";
localNotif.alertAction = #"Show me";
localNotif.applicationIconBadgeNumber = 1;
localNotif.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}];
W
I have several objects inside an array, each object has it's own date.
I want to fire a local notification whenever the the current date == object date.
I have some code, i would like someone to tell me if it makes sense and if it should work, i have taken care of the delegates and reloadData method.
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"LiveIdent";
LiveViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
LiveMatchObject *item = [tableDataLiveMatch objectAtIndex:(int)([indexPath row]/2)];
if ([item isKindOfClass:[LiveMatchObject class]]) {
NSString * dateString = [NSString stringWithFormat: #"%#",item.matchDate];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate* myDate = [dateFormatter dateFromString:dateString];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"'Hoje ás' HH:mm 'horas"];
NSString *stringFromDate = [formatter stringFromDate:myDate];
//// starts here the notification code
// create a timer to keep track of the current date
NSDate *now = [NSDate date];
NSDateFormatter *daterFormatter = [[NSDateFormatter alloc] init];
[daterFormatter setTimeZone:[NSTimeZone systemTimeZone]];
// if current date = date stored in the object then do this
if (myDate == now){
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = myDate;
localNotification.alertBody = #"Início da partida";
localNotification.alertAction = #"Show me the item";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
}
NSArray *localNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
UILocalNotification *localNotification = [localNotifications objectAtIndex:indexPath.row];
[cell.textLabel setText:localNotification.alertBody];
[cell.detailTextLabel setText:[localNotification.fireDate description]];
return cell;
}
Should this work or this is a total disaster?
P.S - i cannot test, because i reads from live events which actually will occur tomorrow, so i'll have to wait, to see it for myself.
Thank you.
Yes your code is looking good but you can test your local-notification by setting some near time instead of waiting for tomorrow here is the code which I used in my project:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay: 16];
[components setMonth: 3];
[components setYear: 2014];
[components setHour: 10];
[components setMinute:32];
[components setSecond: 0];
[calendar setTimeZone: [NSTimeZone defaultTimeZone]];
NSDate *dateToFire = [calendar dateFromComponents:components];
Hope this will helps you.
Currently I have two NSDateFormatters in my app and I want to somehow "combine" them so I only have, since they're parsing the same date.
I have a NSObject called UpcomingReleases, thats where all my JSON info gets stored.
UpcomingRelease.h
- (NSString *) formattedDate;
UpcomingRelease.m
- (NSString *) formattedDate {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:self.release_date];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
My UICollectionViewController (UpcomingReleasesViewController.m)
if([upcomingReleaseDictionary objectForKey:#"release_date"] != NULL)
{
NSString *readableDate = [upcomingReleaseDictionary objectForKey:#"release_date"];
UpcomingRelease *upcoming = [[UpcomingRelease alloc] init];
upcoming.release_date = readableDate;
cell.release_date.text = [NSString stringWithFormat:#"%#", upcoming.formattedDate];
}
My detailedViewController (ReleaseViewController.m)
(_singleRelease is a NSDictionary)
- (void)viewDidLoad
{
[super viewDidLoad];
if([_singleRelease objectForKey:#"release_date"] != NULL)
{
NSString *readableDate = [_singleRelease objectForKey:#"release_date"];
UpcomingRelease *singleRelease = [[UpcomingRelease alloc] init];
singleRelease.release_date = readableDate;
self.release_date.text = [NSString stringWithFormat:#"%#", singleRelease.formattedDate];
}
}
This was working fine, until I added a share on twitter action and I had to add another NSDateFormatter so it could show the readable date inside the tweet (I would get an error saying "No visible interface for ReleaseViewController declares the selected 'formattedDate'" otherwise).
- (NSString *) formattedDate:(NSString *)jsonDateString {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:jsonDateString];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
#pragma mark - Share on twitter
- (IBAction)shareOnTwitter:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
NSString *formattedDate = [self formattedDate:[_singleRelease objectForKey:#"release_date"]];
[tweetSheet setInitialText:[NSString stringWithFormat:#"%#", formattedDate]];
[self presentViewController:tweetSheet animated:YES completion:nil];
}
}
How can I combine both these NSDateFormatters into one? They're both parsing the same string in the same way (also if there's a better way to show the formattedDate string than the one I'm currently doing would be great).
This is how my JSON shows the date string:
release_date: "2013-11-16T00:00:00.000Z"
Thanks.
As #Hot Licks says:
Make the date formatter a class method:
+ (NSString *) formattedDate:(NSString *)jsonDateString {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:jsonDateString];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
Put it in a utility class and use it in both cases. In the first case just pass in self.release_date.