Добавление события в календарь очень медленно

Я просто хочу добавить событие в календарь устройства.

Я использую:

 __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];
             }
         }
     }];

а в iOS 6 это может занять 6/7 секунд (iPhone 4), а на iOS 7 (на iPhone 5S) требуется ~ 10 секунд. Это нормальное поведение? Если не то, что я делаю неправильно?

Ответ 1

У меня была такая же проблема. Благодаря ответу Джаспера, я подумал о очередях. Попробуйте следующее:

    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

Ответ 2

В соответствии с документами: "Для объекта EKEventStore требуется относительно большое количество времени для инициализации и выпуска"., поэтому вы должны отправить это в фоновом режиме.

Кроме того, как ни странно, для основной очереди требуется больше времени, чем фоновая очередь - не знаете, почему это так!