Добавление события в календарь очень медленно
Я просто хочу добавить событие в календарь устройства.
Я использую:
__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 требуется относительно большое количество времени для инициализации и выпуска"., поэтому вы должны отправить это в фоновом режиме.
Кроме того, как ни странно, для основной очереди требуется больше времени, чем фоновая очередь - не знаете, почему это так!