10

I am simply wanting to add an event to the device's calendar.

I'm using:

 __weak ProgramViewController *weakSelf = self;

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

    [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
     {
         if (error)
              NSLog(@"EKEventStore error = %@", error);

         if (granted)
         {
             NSLog(@"EKEvent *event ");

             EKEvent *event = [EKEvent eventWithEventStore:store];
             event.title = weakSelf.program.title;
             event.location = weakSelf.program.locationPublic;
             event.startDate = weakSelf.program.startTime;
             event.endDate = weakSelf.program.endTime;
             [event setCalendar:[store defaultCalendarForNewEvents]];
             NSError *err = nil;
             [store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];

             if (err)
             {
                 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Calendar Error" message:err.localizedDescription delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
                 [alertView show];
             }
             else
             {
                 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Added" message:@"Calendar event added." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
                 [alertView show];
             }
         }
     }];

and in iOS 6 it can take 6/7 seconds (iPhone 4) and on iOS 7 (on an iPhone 5S) it takes ~10 seconds. Is this normal behaviour? If not what am I doing wrong?

4

2 回答 2

12

我遇到过同样的问题。感谢 Jasper 的回答,我开始考虑排队。尝试这个:

    if (!err)
    {
        dispatch_async(dispatch_get_main_queue(),
        ^{
            [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"event added", nil) message:nil delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil] show];
        });
    }

这就是为什么需要这样做(见重点)

讨论

在 iOS 6 及更高版本中,请求访问事件存储会异步提示您的用户授予使用其数据的权限。只有在您的应用第一次请求访问实体类型时才会提示用户;EKEventStore 的任何后续实例化都使用现有权限。当用户点击以授予或拒绝访问时,将在任意队列上调用完成处理程序。当用户决定授予或拒绝权限时,您的应用程序不会被阻止。

由于 UIAlertView 是 UIKit,而 UIKit 总是需要主线程,任何其他任意线程都会崩溃或导致不可预知的行为。

https://developer.apple.com/library/ios/documentation/EventKit/Reference/EKEventStoreClassRef/Reference/Reference.html

于 2013-10-19T13:22:25.170 回答
2

根据文档:“一个 EKEventStore 对象需要相对大量的时间来初始化和释放。” . . 所以你应该在后台队列上调度它。

此外,奇怪的是,主队列比后台队列花费更长的时间——不知道为什么会这样!

于 2013-10-17T03:04:01.783 回答