2013-10-14 17 views
10

Po prostu chcę dodać wydarzenie do kalendarza urządzenia.Dodawanie wydarzenia do kalendarza bardzo powolne

Używam:

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

w iOS 6 może potrwać 6/7 sekundy (iPhone 4), a na iOS 7 (na iPhone 5S) trwa ~ 10 sekund. Czy to normalne zachowanie? Jeśli nie, to co robię źle?

Odpowiedz

12

Miałem ten sam problem. Dzięki odpowiedzi Jaspera pomyślałem o kolejkach. Spróbuj tego:

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

Oto dlaczego jest to potrzebne (patrz nacisk)

Dyskusja

W iOS 6 i później, żądając dostępu do składnicy zdarzeń asynchronicznie prosi swoich użytkowników o pozwolenie na wykorzystanie ich danych. Użytkownik jest pytany tylko za pierwszym razem, gdy aplikacja żąda dostępu do typu jednostki; wszelkie kolejne wystąpienia EKEventStore używają istniejących uprawnień: . Gdy użytkownik kliknie, aby przyznać lub odmówić dostępu, procedura obsługi zakończenia zostanie wywołana w arbitralnej kolejce. Twoja aplikacja nie jest zablokowana, gdy użytkownik decyduje o udzieleniu lub odmowie pozwolenia.

Ponieważ UIAlertView jest UIKit, a UIKit zawsze wymaga głównego wątku, dowolny inny dowolny wątek ulegnie awarii lub doprowadzi do nieprzewidywalnego zachowania.

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

+0

Ciekawe, że to działa - nadal wysyłasz do głównej kolejki. –

+1

@JasperBlues zobacz moją edycję. – mmackh

+0

Dobra robota. @daidai, proszę zmienić, aby zaakceptować tę odpowiedź - będzie bardziej przydatna dla kolejnych widzów. –

2

Zgodnie z dokumentacją: "Obiekt EKEventStore wymaga stosunkowo dużo czasu na zainicjowanie i zwolnienie.". . więc powinieneś wysłać to w kolejce w tle.

Co dziwne, zajmuje więcej czasu w głównej kolejce niż kolejka tła - nie wiem, dlaczego tak jest!

+0

To bardzo dziwne - w moich testów, może to potrwać do 30 sekund w głównym wątku, podczas których swoją UI jest zablokowane, natomiast umieścić go w innym wątku i to dość dużo natychmiastowa ! – siburb

+0

Muszę zapisać 40000 zdarzeń i już używam kolejki tła, czy istnieje jakieś podejście przyjazne wydajności, aby to osiągnąć? – Mrug

Powiązane problemy