Repeat UILocalNotification on Specific day
Asked Answered
K

5

6

I need to set UILocalNotification, I just need to take hour and minute from DatePicker and need to set specific date ( like : Monday ) and repeat it on every Monday.

I have two question about it :

First one ; is it possible to show only "day names" like "Sunday" on the date section of date picker?

Second question is ; what is the correct codes if i want to set specific date for local notification ?

Thank you for the answers and here is my code below ;

-(IBAction) alarmButton:(id)sender {

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterShortStyle;

NSString *dateTimeString = [dateFormatter stringFromDate: dateTimePickerSet1.date];
NSLog ( @"Alarm Set :%@" , dateTimeString);

[self scheduleLocalNotificationWithDate1: dateTimePickerSet1.date];

}

-(void)scheduleLocalNotificationWithDate1:(NSDate *)fireDate {
UILocalNotification *notification = [[UILocalNotification alloc] init];

notification.fireDate = fireDate;
notification.alertBody = @"Alarm Set !";

[[UIApplication sharedApplication] scheduleLocalNotification:notification];
Kellene answered 31/1, 2014 at 14:5 Comment(1)
Check - useyourloaf.com/blog/2010/09/13/… or you can also get some help from #14769962 or #18014938Incentive
J
8

Question 1 => I can not understand what you want. (But if you want to display only name of days such like sunday, monday,....to saturday then use UIPickerView.)

Question 2 => YES you can get correct date of specific day and you can get notification on every specific day by set localNotification.repeatInterval = NSWeekCalendarUnit;

For achieve it, also need to use following piece of (method's) code. This method will return correct date of specific selected day, you just need to pass day as parameter of method such like,

If selected day is sunday then pass 1
If selected day is monday then pass 2
.
.
.
If selected day is saturday then pass 7

Here is method code :

-(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:[NSDate date]];
  NSInteger currentWeekday = dateComponents.weekday;
  NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
  NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
  daysComponents.day = differenceDays;
  NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
  return resultDate;
}

And don't forget to set localNotification.repeatInterval = NSWeekCalendarUnit;

Jenn answered 31/1, 2014 at 14:14 Comment(3)
Thank you very much for your response but i need little more help regarding answer no: 2. is it possible to get some sample code about how to use your answer with date picker config? i am not quite sure where i have to implement this :( thank you very much again @JennKellene
After spending couple of hour to understand your method then i implement it and now it worked perfectly ! Thank you @iPatel.Kellene
@Kellene Why when i installed fireDate 7-Sunday my notification appear every day on current time, but i set 7-Sunday, already tried 4 examples with the same code but no one good solution, what i am doing wrong?Peterkin
S
0

Here's @iPatel's solution that also factors in the time component passed in via the datepicker. (I also updated his solution to use the latest calendar units that aren't deprecated).

- (NSDate *) getFireDateForDayOfWeek:(NSInteger)desiredWeekday withTime:(NSDate *)time // 1:Sunday - 7:Saturday
{
    NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSCalendarUnitWeekday];
    NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;

    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];
    NSInteger currentWeekday = dateComponents.weekday;
    NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;

    NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
    daysComponents.day = differenceDays;
    NSDate *fireDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];

    NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:     NSCalendarUnitHour | NSCalendarUnitMinute fromDate:time];
    NSDateComponents *fireDateComponents = [[NSCalendar currentCalendar]
                components: NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond
                fromDate:fireDate];

    fireDateComponents.hour = timeComponents.hour;
    fireDateComponents.minute = timeComponents.minute;
    fireDateComponents.second = 0;

    NSDate *resultDate = [[NSCalendar currentCalendar] dateFromComponents:fireDateComponents];

    // The day could be today but time is in past. If so, move ahead to next week
    if(resultDate.timeIntervalSinceNow < 0) {
        resultDate = [resultDate dateByAddingTimeInterval:60 * 60 * 24 * 7];
    }

    return resultDate;
}
Stratocumulus answered 25/12, 2014 at 21:50 Comment(1)
Oren, How are you? for the last couple hours im trying to understand your code , it's exactly what i need but it doesn't seems to work. Please contact me as fast as you can , I been working on something for 3 days and still haven't figure this simple part lol. Toda Ahi :) [email protected]Daiquiri
H
0

This solution also takes time in account but it's a bit more simplified than Oren's

-(NSDate *) dateOfSpecificDay:(NSInteger ) day withFireTime:(NSDate *)timeDate/// here day will be 1 or 2.. or 7 and timeDate the current day with the desired time 
{
    NSInteger desiredWeekday = day;
    NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSCalendarUnitWeekday];
    NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;

    NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];
    NSInteger currentWeekday = dateComponents.weekday;
    NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
    if (differenceDays == 0) {
        //Check if should register for same day or for next week
        if ([timeDate compare:[NSDate date]] == NSOrderedAscending) {
            //Should schedule for next week
            differenceDays = daysInWeek;
        }
    }

    NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
    daysComponents.day = differenceDays;
    NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:timeDate options:0];

    return resultDate;
}
Hesione answered 10/12, 2015 at 21:16 Comment(0)
B
0

Here is the swift version:

func calculateTheNExtFriday(inputTime: NSDate) -> NSDate {
    let desiredWeekday = 6 // Friday

    let weekDateRange = NSCalendar.currentCalendar().maximumRangeOfUnit(NSCalendarUnit.Weekday)
    let daysInWeek = weekDateRange.length - weekDateRange.location + 1;

    let currentWeekday = NSCalendar.currentCalendar().components(NSCalendarUnit.Weekday, fromDate: inputTime).weekday
    let differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek

    let dateComponents = NSDateComponents()
    dateComponents.day = differenceDays

    let calculatedFridayDate = NSCalendar.currentCalendar().dateByAddingComponents(dateComponents, toDate: inputTime, options: NSCalendarOptions.init(rawValue: 0))
    return calculatedFridayDate!
}

In this example, I use the desiredWeekday inside the function but you can use it as parameter as well.

NB: Keep in mind that the day 1 corresponds to Sunday, 2 -> Monday and so on

Barcellona answered 9/3, 2016 at 18:19 Comment(0)
W
0

Swift 3:

func calculateSpecificDay(_ desiredWeekday: NSInteger, fromDate: Date = Date()) -> Date {

    let weekDateRange = NSCalendar.current.maximumRange(of: .weekday)!
    let daysInWeek = weekDateRange.lowerBound.distance(to: weekDateRange.upperBound) - weekDateRange.lowerBound + 1

    let currentWeekday = NSCalendar.current.dateComponents([.weekday], from: fromDate).weekday
    let differenceDays = (desiredWeekday - currentWeekday! + daysInWeek) % daysInWeek

    var dateComponents = DateComponents()
    dateComponents.day = differenceDays

    let calculatedFridayDate = NSCalendar.current.date(byAdding: dateComponents, to: fromDate)
    return calculatedFridayDate!
}
If selected day is sunday then pass 1
If selected day is monday then pass 2
.
.
.
If selected day is saturday then pass 7
Wounded answered 3/2, 2017 at 10:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.