EKRecurrenceRule (синхронизация календаря xcode iOS - плагин Phonegap): помощь в создании довольно сложного шаблона событий

Я успешно модифицировал плагины Calendar.m и Calendar.h для iPhone, чтобы создать довольно сложное событие:

В течение определенного месяца три недели имеют одно событие каждые 7 дней, а в последнюю неделю месяца ничего не происходит.

Это сработало, пока я не осознал 2 вещи: 1. Это конкретный месяц с даты начала. Дата начала может быть в любом месте месяца, середины или конца или начала. 2. У всех месяцев не обязательно есть 28 дней. Я должен учитывать 29, 30, 31. 3. Дата окончания, как и дата начала, необязательно также с начала месяца или конца месяца.

Оператор EKRecurrenceRule:

EKRecurrenceRule* rrule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly
interval:1
daysOfTheWeek:nil
daysOfTheMonth:validDays monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:rend];

Мой массив validDays (добавлен в daysOfTheMonth, выше)

//Note: 22 is week 4. This will be excluded. 
validDays = [[NSArray alloc]initWithObjects:
[NSNumber numberWithInt:1],
[NSNumber numberWithInt:8],
[NSNumber numberWithInt:15],
[NSNumber numberWithInt:29], nil];

Для удобства EKAlarm btw имеет смещение 0.

Да, его довольно жестко, пока. Я знаю, что мне нужно изменить массив validDays, и я знаю, как получить номер дня в текущий день, но я не знаю, куда идти отсюда. Документация для EKRecurrenceRule, похоже, не охватывает случаи осложнений за пределами тех, которые начинаются с начала месяца и заканчиваются в конце месяца.

Изменение даты начала и окончания, по крайней мере, в iOS7, похоже, не делает автоматические смещения. Если я начну 10-го числа месяца, f'rex, первое напоминание на 15-м (восьмое и первое прошло) - когда я хочу первое напоминание 17-го числа. Первое напоминание должно быть 7 дней с даты начала и каждое напоминание спустя 7 дней после, с 1 недельным перерывом каждые 3 недели.

В настоящее время у меня создается впечатление, что для начала работы в середине месяца и для неравных длительностей в месяц мне, вероятно, придется создавать несколько EKRecurrenceRules, а также с расширением нескольких недельных или даже месячных событий, которые не считаются повторяющимися событиями. Это не желаемый результат, так как такие события - боль, которую нужно удалить в календаре.

Любая помощь?

1 ответ

В третий раз отвечая на мой вопрос в этом месте.

Изменение: Я понимаю, что эта последовательность событий предназначена для серии событий, которая составляет 21 день/месяц, начиная с произвольного местоположения в месяц, до даты окончания.Я подберу код позже, чтобы ответить на вопрос, но это решение связано с ответом на вопрос, включая ограничения.

Следующие действия действительны только в течение 1 года. Если вы решите использовать это более 1 года, удачи, я действительно не могу вычислить что-то подобное, особенно учитывая високосные годы.

NSMutableArray *validDays = [[NSMutableArray alloc] init];
 NSMutableArray *ignoreDays = [[NSMutableArray alloc] init];
 //according to this algorithm, I only have 28 days a month. Even if a month has 31 or 30 or 29 days. This is because the schedule is counted by WEEK.
 NSInteger currday = 1;

 //excludeWeek denotes the week of a given month that I'll exclude, eg: 1 is the first week, 4 is the last week. This allows me to exclude any week of a given 28-day cycle. 

 switch (excludeWeek)
 {

 case 1:
 for (NSInteger i = 1; i <= 7; ++i)
 {
 [ignoreDays addObject:[NSNumber numberWithInt:i]];
 }
 break;

 case 2:
 for (NSInteger i = 8; i <= 14; ++i)
 {
 [ignoreDays addObject:[NSNumber numberWithInt:i]];
 }

 break;

 case 3:
 for (NSInteger i = 15; i <= 21; ++i)
 {
 [ignoreDays addObject:[NSNumber numberWithInt:i]];
 }

 break;

 default: //or case 4:

 for (NSInteger i = 22; i <= 28; ++i)
 {
 [ignoreDays addObject:[NSNumber numberWithInt:i]];
 }
 break; 
 }

 //this line here is why I can only guarantee results of 1 year. Anything more and endDay may very well be 1 day after startday. I'm using day of year, the only possible values are 1-365 or -1 to -365, +-1 for leap years. 
 if (startDay == endDay) endDay -= 1;

 while (startDay != endDay)
 {

 ++startDay;

 if (isLeapYear)
 {
 //Feb has 1 more day remember?
 if (startDay > 366) startDay = 1;
 }
 else
 {
 if (startDay > 365) startDay = 1;
 }


 if ([ignoreDays containsObject:[NSNumber numberWithInteger:currday] ] == FALSE)

 [validDays addObject: [NSNumber numberWithInt:startDay]];

 ++currday;
 if (currday > 28) currday = 1;
 }

 EKRecurrenceRule* rrule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:EKRecurrenceFrequencyYearly
 interval:1
 daysOfTheWeek:nil
 daysOfTheMonth:nil 
 monthsOfTheYear:nil 
 weeksOfTheYear:nil 
 daysOfTheYear:[NSArray arrayWithArray:validDays] 
 setPositions:nil end:rend];

Надеюсь, кому-то не нужна сложная последовательность, которая длится дольше года. С помощью этого метода вы должны знать, как заполнять недели года таким же образом.

Это по-прежнему вызывает запуск в отдельном потоковом предупреждении, но это намного быстрее, чем выполнение вручную.

licensed under cc by-sa 3.0 with attribution.