I'm having trouble verifying if an event already exists on the user's calendar. I need to check this to determine if I should add it or not, so that I don't create duplicate calendar entries. Right now, I create a duplicate entry every time I run the code.
First, here is how I am creating the calendar entry:
+ (NSString *) addEventToCalenderWithDate : (NSDate *) eventDate
eventTitle : (NSString *) eventTitle
eventLocation : (NSString *) eventLocation
allDayEvent : (BOOL) isAllDay
{
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) {
returnValue = @"calendar error";
}
else if ([self eventExists:dateAndTime eventTitle:eventTitle allDayEvent:isAllDay]) {
returnValue = @"duplicate";
}
else {
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = eventTitle;
event.startDate = dateAndTime;
if (eventTimeString == (id)[NSNull null] || eventTimeString.length == 0 || isAllDay) {
event.allDay = YES;
event.endDate = dateAndTime;
} else {
event.endDate = [event.startDate dateByAddingTimeInterval:60*60]; //set 1 hour meeting
}
event.location = eventLocation;
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
returnValue = @"success";
}
}];
return returnValue;
}
This sets the event correctly. However, if I run it again, I expect that the else if clause will return YES
and no new entry will be created. However, it always returns NO
and I create a new calendar entry with each execution. Here is that method:
+ (BOOL) eventExists : (NSDate *) date
eventTitle : (NSString *) eventTitle
allDayEvent : (BOOL) isAllDay
{
EKEventStore *store = [[EKEventStore alloc] init];
NSPredicate *predicateForEventOnDate = [[NSPredicate alloc] init];
if (isAllDay)
predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:date calendars:nil]; // nil will search through all calendars
else
predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:[date dateByAddingTimeInterval:60*60] calendars:nil]; // nil will search through all calendars
NSArray *eventOnDate = [store eventsMatchingPredicate:predicateForEventOnDate];
NSLog(@"eventOnDate: %@", eventOnDate);
BOOL eventExists = NO;
for (EKEvent *eventToCheck in eventOnDate) {
if ([eventToCheck.title isEqualToString:eventTitle]) {
eventExists = YES;
}
}
return eventExists;
}
As I step through this method, I notice that the NSArray
called eventOnDate
is nil
(the EKEventStore
is not nil
). I don't know if this means that it simply did not find any matching events or if something else is going on.
What am I doing wrong that won't allow this to identify existing events on the calendar? Thank you!
The problem appears to be with the date range you have selected for your predicate.
predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:date calendars:nil];
This will look for events within a "0" second range because the start and end date of your predicate query is identical.
predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:[date dateByAddingTimeInterval:60*60] calendars:nil];
This will only look for events that lie within an hour of the date provided.
NSCalendar *const calendar = NSCalendar.currentCalendar;
NSCalendarUnit const preservedComponents = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay);
//strip away hours, minutes and seconds to find date - at start of day
NSDateComponents *startComponents = [calendar components:preservedComponents fromDate:self.date];
//set finished date to 1 full day later
NSDateComponents *offset = [[NSDateComponents alloc] init];
[offset setDay:1];
NSDate *start = [calendar dateFromComponents:startComponents];
NSDate *finish = [calendar dateByAddingComponents:offset toDate:self.date options:0];
NSPredicate *predicateForEventOnDate = [[NSPredicate alloc] init];
if (isAllDay)
predicateForEventOnDate = [store predicateForEventsWithStartDate:start endDate:finish calendars:nil];
NSArray *eventOnDate = [store eventsMatchingPredicate:predicateForEventOnDate];
This will produce an array that covers events for the full day from start to finish.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With