6

I'm new to iOS programming and I am working on a easy project that lists holidays from a given city and gives users the ability to add those events to the iCal default calendar.

The issue is: how to check if there is already an event with same properties (title and start date for example) in the user's calendar. This could happen if the action button (used to add an event to iCal) is pressed more than once. In such a situation, I don't want two or more identical events being created in iCal.

I have tried to use NSPredicate but I am totally lost on how to get it sorted.

Any help would come be appreciated! Thanks in advance.

Bellow is my event-adding code just to make things clear. In this case a user is adding multiple events from a list (all local holidays for example).

for (int i = 0; i<[allHolidayNames count]; ++i) {

    // ------ EVENT MANIPULATION ------

    EKEventStore *eventStore = [[EKEventStore alloc] init];
    EKEvent *addEvent = [EKEvent eventWithEventStore:eventStore];
    addEvent.title = [allHolidayNames objectAtIndex:i];
    addEvent.startDate = [allHolidayDates objectAtIndex:i];
    addEvent.allDay = YES;
    [addEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
    [eventStore saveEvent:addEvent span:EKSpanThisEvent commit:YES error:nil];
}   
yuji
  • 16,695
  • 4
  • 63
  • 64
lsp
  • 171
  • 1
  • 5
  • 10

1 Answers1

15

Summary

At some point in your instance method (probably during the for loop) you will want to create an NSPredicate based on [allHolidayDates objectAtIndex:i] to return an array that you loop through to check if [allHolidayNames objectAtIndex:i] is present in the returned events.

Example code

for (int i = 0; i<[allHolidayNames count]; ++i) {

    // ------ EVENT MANIPULATION ------

    EKEventStore *eventStore = [[EKEventStore alloc] init];

    NSPredicate *predicateForEventsOnHolidayDate = [eventStore predicateForEventsWithStartDate:[allHolidayDates objectAtIndex:i] endDate:[allHolidayDates objectAtIndex:i] calendars:nil]; // nil will search through all calendars

    NSArray *eventsOnHolidayDate = [eventStore eventsMatchingPredicate:predicateForEventsOnHolidayDate]

    BOOL eventExists = NO;

    for (EKEvent *eventToCheck in eventsOnHolidayDate) {
        if ([eventToCheck.title isEqualToString:[allHolidayNames objectAtIndex:i]]) {
            eventExists = YES;
        }
    }

    if (eventExists == NO) {
        EKEvent *addEvent = [EKEvent eventWithEventStore:eventStore];
        addEvent.title = [allHolidayNames objectAtIndex:i];
        addEvent.startDate = [allHolidayDates objectAtIndex:i];
        addEvent.allDay = YES;
        [addEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
        [eventStore saveEvent:addEvent span:EKSpanThisEvent commit:YES error:nil];
    }
}

Tips

  • To help visualise the data, especially the contents of arrays and objects, try using NSLog. This will output the contents of an object to the console to help you understand the data structures a bit better.

    NSLog("eventsOnHolidayDate = %@",eventsOnHolidayDate);

  • Note that eventsMatchingPredicate will block the main thread whilst retrieving events. If your doing this multiple times in a row it could impact on the user experience. You should consider using enumerateEventsMatchingPredicate:usingBlock: (outside the scope of this question).

craigmarch
  • 534
  • 3
  • 9
  • Thanks man!! I the max value that i can have at one time is 10. So in this case the worst case is eventsMatchingPredicate being execute 10 times. Considering i am totally noob, is that amount enough to decrease user experience? – lsp Feb 19 '12 at 02:46
  • It's really difficult to say. Gut instinct says it should be okay but the best thing to do is try it and see what you think. – craigmarch Feb 19 '12 at 07:47
  • Thanks for the help, after running the application on a real iPhone, I haven't noticed any negative impact on the user experience. – lsp Mar 03 '12 at 21:22
  • Well, now i got another problem. Turns out that i need to format a NSString into a NSDate using NSDateFormatter. The process ran with no problem, but now the duplicity function is not working at all. Here is the code i am using: – lsp Apr 20 '12 at 02:59
  • Agreed to your answer, but identifying an event 'uniquely' is possible only based on the event title? Is there any other way where we can uniquely identify the event? There is a readonly property "eventIdentifier" which would be set by the system, but isnt there any other way to store some information in Event which will help us pick up the event from calendar uniquely? – Raj Pawan Gumdal Apr 03 '14 at 13:40
  • I don't believe so, although I haven't checked out the latest API for iOS 7 so it might have changed. – craigmarch Apr 04 '14 at 22:41