Check if NSDate is within an EKEventStore

525 Views Asked by At

I'm trying to check whether a certain nsdate is within my Event Store. The current month events are stored in a NSMutableArray. I'm using the these functions to create the events store and to fetch objects on it :

- (void) viewDidLoad{
[super viewDidLoad];

    self.almacenEventos = [EKEventStore new];
    self.listaEventos = [NSMutableArray new];

    self.calendario = [self.almacenEventos defaultCalendarForNewEvents];

    [self.listaEventos addObjectsFromArray:[self monthEvents]];

}

-(NSArray *) monthEvents{

    NSDate *firstMonthDay = [NSDate firstDayOfCurrentMonth];

    NSDate *lastMonthDay = [NSDate firstDayOfNextMonth];

    NSArray *calendarios = [[NSArray alloc]initWithObjects:self.calendario, nil];

    NSPredicate * predicado = [self.almacenEventos predicateForEventsWithStartDate:firstMonthDay endDate:lastMonthDay calendars:calendarios];

    return [self.almacenEventos eventsMatchingPredicate:predicado];
}

firstDayOfCurrentMonth and firstDayOfNextMonth will return correctly the dates of the current month. After initialization, self.listaEventos has all current month events.

The problem comes up when checking if a self.almacenEventos contains a NSDate. I'm using tapku calendar to display a month grid. And following all instructions form developer and other 3rd party help as well.

I've debugged the code, trying to find the issue. "d" which is the date to compare with, returns a long format 2012-08-29 00:00:00 +0000.

a single event has this format for dates:

startDate = 2012-08-04 22:00:00 +0000;
endDate = 2012-08-05 21:59:59 +0000;

So I'm stuck in the middle of this function, where a date given object is present in the array. If I use a manual array of dates, instead of the events array, it works like a charm.....so what am I doing wrong here? is it the returned NSDateComponents? How can I do it? thanks so much

- (NSArray*) checkDate:(TKCalendarMonthView*)monthView marksFromDate:(NSDate*)startDate toDate:(NSDate*)lastDate{

    NSMutableArray *marks = [NSMutableArray array];

    NSCalendar *cal = [NSCalendar currentCalendar];
    [cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    NSDateComponents *comp = [cal components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:startDate];

    NSDate *d = [NSDate new];
    d = [cal dateFromComponents:comp];

    // Init offset components to increment days in the loop by one each time
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setDay:1];

    // for each date between start date and end date check if they exist in the data array
    while (YES) {      

        // Is the date beyond the last date? If so, exit the loop.
        // NSOrderedDescending = the left value is greater than the right
        if ([d compare:lastDate] == NSOrderedDescending) {
            break;
        }

        // If the date is in the data array, add it to the marks array, else don't
        if ([self.listaEventos containsObject:d]) {
            [marks addObject:[NSNumber numberWithBool:YES]];
        } else {
            [marks addObject:[NSNumber numberWithBool:NO]];
        }

        // Increment day using offset components (ie, 1 day in this instance)
        d = [cal dateByAddingComponents:offsetComponents toDate:d options:0];
    }

    return [NSArray arrayWithArray:marks];

}
1

There are 1 best solutions below

2
On

The checkDate:marksFromDate:toDate method expects self.listaEventos to be a NSMutableDictionary indexed by dates containing an array of EKEvent:

// There are events on these 4 dates
self.listaEventos = {
    "2012-08-15 00:00:00 +0000" = (...),
    "2012-08-17 00:00:00 +0000" = (...),
    "2012-08-18 00:00:00 +0000" = (...),
    "2012-08-29 00:00:00 +0000" = (...)
}

I would change monthEvents to something like:

-(NSMutableDictionary *) monthEvents{
    NSMutableDictionary *retVal;

    NSDate *firstMonthDay = [NSDate firstDayOfCurrentMonth];
    NSDate *lastMonthDay = [NSDate firstDayOfNextMonth];
    NSArray *calendarios = [[NSArray alloc]initWithObjects:self.calendario, nil];
    NSPredicate * predicado = [self.almacenEventos predicateForEventsWithStartDate:firstMonthDay endDate:lastMonthDay calendars:calendarios];

    NSArray *results = [self.almacenEventos eventsMatchingPredicate:predicado];
    // Next add all events to our dictionary indexed by date
    for (EKEvent *evt in events) {
        NSDate *dateKey = [self dateWithoutTime:evt];

        // A date may have multiple events. Get all current events for the date
        NSArray *eventsForDate = [retVal objectForKey:dateKey];
        // If no events were set for the date
        if (![eventsForDate isKindOfClass:[NSArray class]]) {
            // create an array using a factory method
            eventsForDate = [NSArray arrayWithObject:evt];
        } else {
            // append the object to our array of events
            eventsForDate = [eventsForDate arrayByAddingObject:evt];
        }

        // Update the dictionary
        [retVal setObject:eventsForDate forKey:dateKey];
    }

    return retVal;
}

- (NSDate *)dateWithoutTime:(NSDate *)date 
{
    TKDateInformation info = [date dateInformationWithTimeZone:[NSTimeZone systemTimeZone]];
    // lop off hour/minute/seconds so all dates for the day are equal
    info.hour = 0;
    info.minute = 0;
    info.second = 0;

    return [NSDate dateFromDateInformation:info timeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
}