Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get all events from an EKCalendar in iOS

I've created a calendar with some events, now I want to get all events from that calendar, without knowing what their start or end date is.

Code I tried, getting all events from all calendars, so I could divide them by calendar ID later or so.. :

NSPredicate *fetchCalendarEvents = [eventStore predicateForEventsWithStartDate:[NSDate distantPast] endDate:[NSDate distantFuture] calendars:eventStore.calendars];

NSArray *allEvents = [eventStore eventsMatchingPredicate:fetchCalendarEvents];

This makes allEvents return nil while the database clearly shows events in the calendar.

Anyone could help me?

like image 685
Lofens Avatar asked Oct 16 '12 09:10

Lofens


2 Answers

I have it working now.

This is the code I'm using:

NSDate* endDate =  [NSDate dateWithTimeIntervalSinceNow:[[NSDate distantFuture] timeIntervalSinceReferenceDate]];
NSArray *calendarArray = [NSArray arrayWithObject:cal];
NSPredicate *fetchCalendarEvents = [eventStore predicateForEventsWithStartDate:[NSDate date] endDate:endDate calendars:calendarArray];
NSArray *eventList = [eventStore eventsMatchingPredicate:fetchCalendarEvents];

for(int i=0; i < eventList.count; i++){

    NSLog(@"Event Title:%@", [[eventList objectAtIndex:i] title]);

}

Gives me all events from the calendar I'm using for my app from the date it is right when you call the method.

I think giving [NSDate distantPast] won't work because it's in the past or something.. setting your startDate as [NSDate date] will work.

Hope this helps people who have the same problem..

like image 187
Lofens Avatar answered Sep 28 '22 16:09

Lofens


If you would like to lookup a year span greater than 4 years, the returned events would be trimmed by the system to those from the first 4 years. (see Apple's documentation). What could be a possible solution is to run the predicate matching in batches.

Here's a C# extension for Xamarin.iOS

public static class EKEventStoreExtensions
{        
    private const int MaxPredicateYearSpan = 4;

    public static EKEvent[] GetAllEvents(this EKEventStore eventStore, DateTimeOffset startAt, DateTimeOffset endAt, params EKCalendar[] calendars)
    {
        var isBatched = endAt.Year - startAt.Year >= MaxPredicateYearSpan;
        var result = new List<EKEvent>();
        var batchStartAt = startAt;
        var batchEndAt = endAt;

        while (batchStartAt < endAt)
        {
            if (isBatched)
            {
                batchEndAt = batchStartAt.AddYears(1);
                if (batchEndAt > endAt)
                {
                    batchEndAt = endAt;
                }
            }

            var events = GetEventsMatching(eventStore, batchStartAt, batchEndAt, calendars);
            result.AddRange(events);

            batchStartAt = batchEndAt;
        }

        return result.ToArray();
    }

    private static EKEvent[] GetEventsMatching(EKEventStore eventStore, DateTimeOffset startAt, DateTimeOffset endAt, EKCalendar[] calendars)
    {
        var startDate = (NSDate)startAt.LocalDateTime;
        var endDate = (NSDate)endAt.LocalDateTime;
        var fetchCalendarEvents = eventStore.PredicateForEvents(startDate, endDate, calendars);

        return eventStore.EventsMatching(fetchCalendarEvents);
    }
}
like image 33
Momchil Marinov Avatar answered Sep 28 '22 14:09

Momchil Marinov