【问题标题】:Fetch all events from EventStore EventKit iOS从 EventStore EventKit iOS 中获取所有事件
【发布时间】:2011-05-20 21:08:15
【问题描述】:

我想知道如何在 iOS 中使用 EventKit 从 EventStore 中获取所有事件。

这样我可以指定今天的所有活动:

- (NSArray *)fetchEventsForToday {

    NSDate *startDate = [NSDate date];

    // endDate is 1 day = 60*60*24 seconds = 86400 seconds from startDate
    NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:86400];

    // Create the predicate. Pass it the default calendar.
    NSArray *calendarArray = [NSArray arrayWithObject:defaultCalendar];
    NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendarArray]; 

    // Fetch all events that match the predicate.
    NSArray *events = [self.eventStore eventsMatchingPredicate:predicate];

    return events;
}

正确的应该使用 NSPredicate,它是通过以下方式创建的:

NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendarArray]; 

我尝试过使用

distantPast
distantFuture

作为 startDate 和 endDate,不好。 所以其他 Q 中的其他 A 并不是我要寻找的。​​p>

谢谢!


编辑

我已经测试并得出结论,我最多只能获取 4 年的事件。有什么办法可以过去吗?不使用多次提取..

【问题讨论】:

  • 需要过期事件列表吗?
  • 没错,日历上的每个事件。过去和未来。

标签: iphone ios sdk fetch eventkit


【解决方案1】:

获取所有事件到数组的代码:

NSDate *start = ...
NSDate *finish = ...

// use Dictionary for remove duplicates produced by events covered more one year segment
NSMutableDictionary *eventsDict = [NSMutableDictionary dictionaryWithCapacity:1024];

NSDate* currentStart = [NSDate dateWithTimeInterval:0 sinceDate:start];

int seconds_in_year = 60*60*24*365;

// enumerate events by one year segment because iOS do not support predicate longer than 4 year !
while ([currentStart compare:finish] == NSOrderedAscending) {

    NSDate* currentFinish = [NSDate dateWithTimeInterval:seconds_in_year sinceDate:currentStart];

    if ([currentFinish compare:finish] == NSOrderedDescending) {
        currentFinish = [NSDate dateWithTimeInterval:0 sinceDate:finish];
    }
    NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:currentStart endDate:currentFinish calendars:nil];
    [eventStore enumerateEventsMatchingPredicate:predicate
                                      usingBlock:^(EKEvent *event, BOOL *stop) {

                                          if (event) {
                                              [eventsDict setObject:event forKey:event.eventIdentifier];
                                          }

                                      }];       
    currentStart = [NSDate dateWithTimeInterval:(seconds_in_year + 1) sinceDate:currentStart];

}

NSArray *events = [eventsDict allValues];

【讨论】:

  • 谢谢德米特里!我会尝试并回来!没有人能回答这个简单的问题,希望你能回答!
  • 此代码将起作用,除了它通过仅显示返回的最终事件来合并所有重复事件,因为它使用 eventIdentifier 作为散列键,并且所有重复事件具有相同的散列键。 if (event) { [eventsDict setObject:event forKey:[event.eventIdentifier stringByAppendingString:[event.startDate description]]]; }
  • 注意:不是每年都有 365 天。所以硬编码不是最好的解决方案。
  • 您可能想在不同的线程中调用 predicateForEventsWithStartDate。
【解决方案2】:

这是我在我的应用中用来获取它们的方法。

    NSDate *startDate = [NSDate distantPast];       
    NSDate *endDate = [NSDate distantFuture];

【讨论】:

  • 这会返回所有过去的“完成”事件吗?如果我从 2002 年开始有活动,这会返回所有活动吗?
  • 我应该只在未来使用它
  • 这不会超过 4 年,最长 4 年(未来或过去),有什么想法吗?或者这对你有用吗?
  • 对不起,我从来没有过去 2 年。
  • 这可能曾经有效,但在 iOS 9 中它不起作用。 Apple 现在似乎将startDateendDate 之间的跨度限制为4 年。
【解决方案3】:

这是生产中的代码

const double secondsInAYear = (60.0*60.0*24.0)*365.0;
NSPredicate* predicate = [eventStore predicateForEventsWithStartDate:[NSDate dateWithTimeIntervalSinceNow:-secondsInAYear] endDate:[NSDate dateWithTimeIntervalSinceNow:secondsInAYear] calendars:nil];

对你来说,我建议回顾十年。

【讨论】:

  • 问题是,当我尝试超过一年时,谓词从商店返回 0 个对象。
  • 不,我还没有尝试更进一步——我猜魔法是一年。
  • 所以您建议进行多次提取?我需要每一个事件,过去和未来。重复或不重复等。
  • 注意:不是每年都有 365 天。所以硬编码不是最好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多