The following code receives an array of events from EventKit for the selected day, then "pads" the existing calendar events with empty events to fill hourly slots from the entire day (9-5, for example).
The events coming from the iOS calendar are contained within a custom event container class that I created. The event class has the following properties:
// HDEvent.h
@interface HDEvent : NSObject
@property(nonatomic, copy) NSDate *startDate;
@property(nonatomic, copy) NSDate *endDate;
@property(nonatomic, strong) EKEvent *event;
@property(nonatomic, copy) NSString *eventIdentifier;
@property(nonatomic, copy) NSString *tempTitle;
@end
I am attempting to replace the empty events with any true events from the calendar, based on the start/end dates of the HDEvent
object. The incoming array for the following method has the events (if any) from the device calendar.
- (NSArray *)addEmptyEventsWithEvents:(NSMutableArray *)events
ForDate:(NSDate *)date {
NSMutableOrderedSet *finalEvents = [[NSMutableOrderedSet alloc] init];
// this returns an array filled with the empty HDEvents
// for the expected date range.
NSArray *emptyEvents = [self getEventsTimeRangeFromDate:date];
for (HDEvent *emptyEvent in emptyEvents) {
HDEvent *eventToAdd;
for (HDEvent *event in events) {
NSLog(@"Event: %@", event.event.title);
if ([event.startDate isEqualToDate:emptyEvent.startDate] ||
[event.endDate isEqualToDate:emptyEvent.endDate])
{
eventToAdd = event;
} else {
eventToAdd = emptyEvent;
}
}
[finalEvents addObject:eventToAdd];
}
return [finalEvents array];
}
I am attempting to create an array with my events as illustrated in the pseudo-code below:
// Calendar Events
[
10:00-11:00 MEETING,
11:00-12:00 LUNCH
]
// Empty Placeholders
[
09:00-10:00 EMPTY,
10:00-11:00 EMPTY,
11:00-12:00 EMPTY,
12:00-01:00 EMPTY,
01:00-02:00 EMPTY,
02:00-03:00 EMPTY,
03:00-04:00 EMPTY,
04:00-05:00 EMPTY,
]
// Final desired result:
[
09:00-10:00 EMPTY,
10:00-11:00 MEETING,
11:00-12:00 LUNCH,
12:00-01:00 EMPTY,
01:00-02:00 EMPTY,
02:00-03:00 EMPTY,
03:00-04:00 EMPTY,
04:00-05:00 EMPTY,
]
[Problem]:
The problem is that the array returned only contains one event from the calendar (though I can see in the NSLog response that I have two events on that day)
If I swap the for loops around, then I get 9 events (again, only one from the calendar, and one duplicate empty event.)
Thank you @vikingosegundo.
I ended up implementing a custom comparison method in my class following the advice contained in this answer here: https://stackoverflow.com/a/877881/810360
I also extended it to be more flexible by utilizing the excellent DateTools by Matthew York found on GitHub: https://github.com/MatthewYork/DateTools
This was my final code:
-(BOOL)isEqualToEvent:(HDEvent*)event {
if (self == event) {
return YES;
}
if ([event.startDate isEqualToDate:self.startDate] &&
[event.endDate isEqualToDate:self.endDate]) {
return YES;
} else {
return NO;
}
}
-(BOOL)doesEventIntersectEvent:(HDEvent*)event {
DTTimePeriod *eventTimePeriod = [DTTimePeriod timePeriodWithStartDate:event.startDate endDate:event.endDate];
DTTimePeriod *selfTimePeriod = [DTTimePeriod timePeriodWithStartDate:self.startDate endDate:self.endDate];
if ([eventTimePeriod intersects:selfTimePeriod]) {
return YES;
} else {
return NO;
}
}
-(BOOL)doesEventContainEvent:(HDEvent*)event {
DTTimePeriod *eventTimePeriod = [DTTimePeriod timePeriodWithStartDate:event.startDate endDate:event.endDate];
DTTimePeriod *selfTimePeriod = [DTTimePeriod timePeriodWithStartDate:self.startDate endDate:self.endDate];
if ([eventTimePeriod contains:selfTimePeriod]) {
return YES;
} else {
return NO;
}
}