问题
I want to get all events from a specific calendar in my app. I created the calendar and the test events in my app (needs iOS 5.0 or later for creating custom calendars). If I run the app on my device and then check the system calendar app then my calendar and my created events are shown correctly.
Now I want my app to read all those events out of this custom calendar. My events are created with startDate and endDate set to NOW (NSDate alloced with no timeInterval given).
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:- 60 * 60 * 24 * (365 * 4 + 1)];
NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24 * 365 * 25];
NSArray *calendarList = [NSArray arrayWithObjects:tmpCal, nil];
NSPredicate *datePredicate = [store predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendarList];
NSArray *eventList = [store eventsMatchingPredicate:datePredicate];
As you can see I am specifying a time interval in which the resulting events have to be. As you can see too, the end date is in 25 years from now on whereas the start date is 4 years (plus one day for leap year) in the past. If I query the EKEventstore in this way, I am getting the previously added events. The tricky part begins if I want to put the start date one (or more days or years) back in the past. Then, suddenly, no events are returned.
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:- 60 * 60 * 24 * (365 * 4 + 2)];
Is there a limit for negative values of a NSTimeInterval in a NSPredicate? I did not found any documented limitations. It took me about 2 hours to detect why I was getting no events (originally I wanted a range of 5 years in the past and 5 years in the future). What is the reason for this curious behaviour? Any idea?
/edit on 04/11/2012
After creating some events with a starting date on 03/31/2012 and 04/20/2012 it seems to be that fetching events by dates determined with intervals from now is limited by an interval length of 4 years. Adjusting my start date (by setting the start day one day earlier) in the given code above I was able to get events until 03/31/2012 but not later ones. Removing this adjustment resulted in getting events from 03/31/2012 and 04/01/2012 (but not those from 04/20/2012). After a second adjustment (setting the start date 20 days later) I got even those future events.
I cannot specify why there is such limitation. May be there are some internal calculations that would lead to overflows of the used value storage. Just a guess.
Then I head to Apple examples. At first glance I did not want to use the given code in the EKEvent Programming Guide of Apple. It did not look as small & cute as mine, but after having so much trouble I gave it a shot.
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFTimeZoneRef timeZone = CFTimeZoneCopySystem();
gregorianStartDate.hour = 0;
gregorianStartDate.minute = 0;
gregorianStartDate.second = 0;
gregorianStartDate.day = 1;
gregorianStartDate.month = 4;
gregorianStartDate.year = 2008;
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
gregorianEndDate.hour = 23;
gregorianEndDate.minute = 59;
gregorianEndDate.second = 59;
gregorianEndDate.day = [components day];
gregorianEndDate.month = [components month];
gregorianEndDate.year = [components year] + 1;
NSDate *startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate *endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
CFRelease(timeZone);
This way I get all events starting from 04/01/2008 up to NOW() + 1 year. Well, it turned out that the same limitation is used here :( Adjusting the start date resulted in getting only a part of my events until the last events were in the range of those 4 years.
Intensive researches showed up that this behaviour exists a very long time: Fetch all events from EventStore EventKit iOS
回答1:
I agree with James pulling too many events in with a date that is so far in the future is not advised, luckily you can use distantFuture to pull in, well distant events.
This obviously does not pull all events but as many events as it can in with out causing memory or other issues.
NSDate *endDate = [NSDate distantFuture];
Hope that helps
回答2:
It's generally a bad thing to query for such a large date range of events from CalendarStore. Performance is horrible pulling a month at a time, and you're wanting to pull "all"? Definitely not advised. Let CalendarStore be the one that has to worry about 'all', and you should focus on how to properly scope the date ranges you need to pull.
For instance, if you have a normal calendar app showing a month at a time, just pull down 3 months (your target month, plus the month in front and back of your current calendar). If someone pages to the next month, then put a request out to get the month after that, and so on.
Maybe you could provide more info on what's driving your desire to get 'all' events?
来源:https://stackoverflow.com/questions/9988843/ekeventstore-getting-events-returns-empty-list