4

I'm trying to add an event into calendar with recurrence rule RRULE:FREQ=YEARLY;BYMONTH=6,7;BYDAY=1TH

So according to this rule the event should be added yearly, each 1st thursday of june and july until expire date, which I've set in my project.

In my project, events are created but not according to the recurrence rule. With the following code the events added only on each 1st thursday of june. Why the events are not added on 1st thursday of each july also?

Here is .m file code

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self createEvent];
}

- (void)createEvent
{
    EKEventStore *eventStore = [[EKEventStore alloc] init];
    EKEvent *event = [EKEvent eventWithEventStore:eventStore];
    event.title = @"testRecurrenceRule";
    event.location = @"Dhaka";
    [event setCalendar:[eventStore defaultCalendarForNewEvents]];
    event.startDate = [self dateFromString:@"2013-06-18T21:00:00+06:00"];
    event.endDate = [self dateFromString:@"2013-06-18T22:00:00+06:00"];

    id recurrenceRule = [self recurrenceRuleForEvent];
    if(recurrenceRule != nil)
        [event addRecurrenceRule:recurrenceRule];

    if ([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)])
    {
        // iOS 6 and later
        [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
            if (granted)
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self saveTheEvent:event eventStore:eventStore];
                    //[eventStore saveEvent:event span:EKSpanThisEvent error:error];
                });
            }
            else
            {
                dispatch_async(dispatch_get_main_queue(), ^{

                    //do nothing
                });
            }
        }];
    }
    else
    {
        [self saveTheEvent:event eventStore:eventStore];
    }

    textView.text = [NSString stringWithFormat:@"Event has been added with recurrence rule %@",recurrenceRule];
}

- (void)saveTheEvent:(EKEvent *)aEvent eventStore:(EKEventStore *)aStore
{
    [aStore saveEvent:aEvent span:EKSpanThisEvent error:NULL];
}

- (EKRecurrenceRule *)recurrenceRuleForEvent
{
    //just creating a recurrence rule for RRULE:FREQ=YEARLY;BYMONTH=6,7;BYDAY=1TH
    // setting the values directly for testing purpose.

    //FREQ=YEARLY
    EKRecurrenceFrequency recurrenceFrequency = EKRecurrenceFrequencyYearly;
    NSInteger recurrenceInterval = 1;                                             
    EKRecurrenceEnd *endRecurrence = nil;                                         
    NSMutableArray *monthsOfTheYearArray = [NSMutableArray array];               
    NSMutableArray *daysOfTheWeekArray = [NSMutableArray array];                
    NSMutableArray *daysOfTheMonthArray = [NSMutableArray array];               
    NSMutableArray *weeksOfTheYearArray = [NSMutableArray array];              
    NSMutableArray *daysOfTheYearArray = [NSMutableArray array];          
    NSMutableArray *setPositionsArray = [NSMutableArray array];         

    //BYMONTH=6,7
    [monthsOfTheYearArray addObject:[NSNumber numberWithInt:6]];
    [monthsOfTheYearArray addObject:[NSNumber numberWithInt:7]];

    //BYDAY=1TH
    [daysOfTheWeekArray addObject:[EKRecurrenceDayOfWeek dayOfWeek:5 weekNumber:1]];

    endRecurrence = [EKRecurrenceEnd recurrenceEndWithEndDate:[self dateFromString:@"2018-12-15T22:30+06:00"]];

    EKRecurrenceRule *recurrence = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:recurrenceFrequency
                                                                                interval:recurrenceInterval
                                                                           daysOfTheWeek:daysOfTheWeekArray
                                                                          daysOfTheMonth:daysOfTheMonthArray
                                                                         monthsOfTheYear:monthsOfTheYearArray
                                                                          weeksOfTheYear:weeksOfTheYearArray
                                                                           daysOfTheYear:daysOfTheYearArray
                                                                            setPositions:setPositionsArray
                                                                                     end:endRecurrence];
    return recurrence;
}

- (NSDate *)dateFromString:(NSString *)string
{
    //check if the date string in null
    if ([string length] == 0)
        return nil;

    NSString *dateString = nil;
    NSString *modifiedString = nil;
    BOOL secSpotMissing = false;

    NSRange range = [string rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"T"]];
    if (range.location != NSNotFound)
    {
        dateString = [string substringFromIndex:range.location];

        range = [dateString rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"+-Z"]];
        if (range.location != NSNotFound)
        {
            //seperate the time portion of date string and checking second field is missing or not. like is it HH:mm or HH:mm:ss?
            if ([[[dateString substringToIndex:range.location] componentsSeparatedByString:@":"] count] < 3)
                secSpotMissing = true;

            //seperate the time zone portion and checking is there any extra ':' on it. It should like -0600 not -06:00. If it has that extra ':', just replacing it here.
            dateString = [dateString substringFromIndex:range.location];
            if([dateString hasSuffix:@"Z"])
                modifiedString = [dateString stringByReplacingOccurrencesOfString:@"Z" withString:@"+0000"];
            else
                modifiedString = [dateString stringByReplacingOccurrencesOfString:@":" withString:@""];
            string = [string stringByReplacingOccurrencesOfString:dateString withString:modifiedString];
        }
    }
    else
        return nil;

    // converting the date string according to it's format.
    NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
    if (secSpotMissing)
        [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mmZZZ"];
    else
        [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"];
    return [dateFormatter dateFromString:string];
}

Can somebody please help me regarding this?

4

2 回答 2

1

这似乎是另一个问题的重复。基本上,根据“BYDAY”规则,YEARLY 频率的第一个表示一年中的第一周 - 而不是每个月的第一周。

@Shuvo,我没有阅读 rfc。但这里是 Apple 文档EKRecurrenceDayOfWeek

EKRecurrenceDayOfWeek 类表示一周中的一天,用于与 EKRecurrenceRule 对象一起使用。一周中的一天可以选择有一个周数,指示重复规则频率中的特定日期。例如,星期几的日期值为星期二,周数为 2,在每月重复规则中表示每个月的第二个星期二,在每年重复规则中表示每年的第二个星期二。

当您说“第一个星期四”时,这是正确的 - 除了在每年的情况下,它是一年中的第一个星期四。

于 2013-09-07T04:38:59.930 回答
0

该漏洞已被 Apple 确认,至少在 iOS 7.1.3 之前(这是目前可用的最新版本)。

于 2014-01-17T08:39:53.150 回答