Выборка событий за указанный промежуток времени с использованием Event Kit не работает должным образом - PullRequest
2 голосов
/ 01 апреля 2011

Я использую Event Kit на iOS 4.3.1 для извлечения всех событий за указанный промежуток времени. Однако у меня возникают следующие проблемы.

1) использование в качестве даты начала [NSDate distantPast] и в качестве даты окончания [NSDate distantFuture] не возвращает ни одного события.

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

    // Create the predicate.
    NSPredicate *eventPredicate = [store predicateForEventsWithStartDate:[NSDate distantPast] endDate:[NSDate distantFuture] calendars:store.calendars]; 

    // Fetch all events that match the predicate.
    NSArray *events = [[store eventsMatchingPredicate:eventPredicate] retain];

2) Установка даты начала на 10 лет назад и даты окончания на 10 лет с этого момента позволяет получать только события до 2005 года. Больше ничего не возвращается.

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

    CFGregorianDate gregorianStartDate, gregorianEndDate;
    CFGregorianUnits startUnits = {-10, 0, 0, 0, 0, 0};
    CFGregorianUnits endUnits = {10, 0, 0, 0, 0, 0};
    CFTimeZoneRef timeZone = CFTimeZoneCopySystem();

    gregorianStartDate = CFAbsoluteTimeGetGregorianDate(
                                                        CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), 
                                                        timeZone, 
                                                        startUnits),
                                                        timeZone);
    gregorianStartDate.hour = 0;
    gregorianStartDate.minute = 0;
    gregorianStartDate.second = 0;

    gregorianEndDate = CFAbsoluteTimeGetGregorianDate(
                                                      CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), 
                                                      timeZone,
                                                      endUnits),
                                                      timeZone);
    gregorianEndDate.hour = 0;
    gregorianEndDate.minute = 0;
    gregorianEndDate.second = 0;

    NSDate* startDate =
    [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
    NSDate* endDate =
    [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];

    CFRelease(timeZone);

    // Create the predicate.
    NSPredicate *eventPredicate = [store predicateForEventsWithStartDate:startDate endDate:endDate calendars:store.calendars]; 

    // Fetch all events that match the predicate.
    NSArray *events = [[store eventsMatchingPredicate:eventPredicate] retain];

Итак, мне было интересно, правильный ли фрагмент размещенного кода или я что-то не так делаю. В идеале я хотел бы использовать [NSDate distantPast] и [NSDate distantFuture], чтобы получить за один вызов все события во всех календарях. Это действительно возможно? Кроме того, поскольку даже второй пример не работает (по крайней мере, для меня), как правильно получить все события? Нужно ли многократные звонки с узким временным интервалом? Если да, какой самый большой интервал времени можно использовать для извлечения событий? Заранее спасибо.

1 Ответ

0 голосов
/ 23 ноября 2011

AFAIK, это правильно.Не похоже, что ошибка в этой части кода.Я перфорировал ваш второй фрагмент в чистое приложение.

    CFGregorianDate gregorianStartDate, gregorianEndDate;
    CFGregorianUnits startUnits = {-10, 0, 0, 0, 0, 0};
    CFGregorianUnits endUnits = {10, 0, 0, 0, 0, 0};
    CFTimeZoneRef timeZone = CFTimeZoneCopySystem();

    gregorianStartDate = CFAbsoluteTimeGetGregorianDate(
                                                        CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), 
                                                        timeZone, 
                                                        startUnits),
                                                        timeZone);
    gregorianStartDate.hour = 0;
    gregorianStartDate.minute = 0;
    gregorianStartDate.second = 0;

    gregorianEndDate = CFAbsoluteTimeGetGregorianDate(
                                                      CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), 
                                                      timeZone,
                                                      endUnits),
                                                      timeZone);
    gregorianEndDate.hour = 0;
    gregorianEndDate.minute = 0;
    gregorianEndDate.second = 0;

    NSDate* startDate =
    [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
    NSDate* endDate =
    [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];

NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init]autorelease];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSLocale *usLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]autorelease];
[dateFormatter setLocale:usLocale];

NSDate * today = [[[NSDate alloc] init] autorelease];

    NSLog(@"Date for locale %@: %@",[[dateFormatter locale] localeIdentifier], [dateFormatter stringFromDate:today]);
    NSLog(@"Date for locale %@: %@",[[dateFormatter locale] localeIdentifier], [dateFormatter stringFromDate:startDate]);
    NSLog(@"Date for locale %@: %@",[[dateFormatter locale] localeIdentifier], [dateFormatter stringFromDate:endDate]); 

    CFRelease(timeZone);

Я получил следующий вывод:

2011-11-23 13: 31: 40.244 Testapp [15440: 207] Дата для локали en_US: 23 ноября 2011 г.

2011-11-23 13: 31: 41.195 Testapp [15440:207] Дата для локали en_US: 23 ноября 2001 г.

2011-11-23 13: 31: 42.063 Testapp [15440: 207] Дата для локали en_US: 23 ноября, 2021

Удачи.

Кстати, я бы использовал NSDateComponent, чтобы получить 10 лет в будущем и 10 лет в прошлом.Добавьте это к приведенному выше коду,

NSDateComponents *yearForPredicate = [[[NSDateComponents alloc] init]autorelease];
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendar:NSGgregorianCalendar]autorelease];
[yearForPredicate setYear:10];
NSDate *distantFuture = [gregorian dateByAddingComponents:yearForPredicate toDate:today options:0];
[yearForPredicate setYear:-10]
NSDate *distantPast = [gregorian dateByAddingComponents:yearForPredicate toDate:today options:0];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...