2013-10-14 9 views
10

Sto semplicemente aggiungendo un evento al calendario del dispositivo.Aggiunta di eventi al calendario molto lento

sto usando:

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

e in iOS 6 può richiedere 6/7 secondi (iPhone 4) e su iOS 7 (su un iPhone 5S) ci vogliono circa 10 secondi. Questo comportamento normale? Se no, cosa sto sbagliando?

risposta

12

Ho avuto lo stesso problema. Grazie alla risposta di Jasper, ho pensato alle code. Prova questo:

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

Ecco il motivo per cui questo è necessario (vedi enfasi)

Discussione

In iOS 6 e versioni successive, richiede l'accesso a un archivio eventi richiede in modo asincrono gli utenti per permesso di usare i loro dati. L'utente viene richiesto solo la prima volta che l'app richiede l'accesso a un tipo di entità; eventuali istanze successive di EKEventStore utilizzano le autorizzazioni esistenti . Quando l'utente tocca per concedere o negare l'accesso, il gestore di completamento verrà chiamato su una coda arbitraria. L'app è non bloccata mentre l'utente decide di concedere o negare l'autorizzazione.

Poiché UIAlertView è UIKit e Uikit richiede sempre il thread principale, qualsiasi altro thread arbitrario si bloccherà o porterà a comportamenti imprevedibili.

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

+0

Interessante che funzioni: si sta ancora arrivando alla coda principale. –

+1

@JasperBlues vedere la mia modifica. – mmackh

+0

Bel lavoro. @daidai si prega di cambiare per accettare questa risposta - sarà più utile per gli spettatori successivi. –

2

Secondo i documenti: "Un oggetto EKEventStore richiede un tempo relativamente lungo per l'inizializzazione e il rilascio.". . quindi dovresti inviarlo su una coda di sfondo.

Inoltre, stranamente, richiede più tempo sulla coda principale rispetto alla coda di sfondo - non è sicuro il motivo per cui questo è!

+0

Questa è la cosa molto strana - nel mio test, potrebbe richiedere fino a 30 secondi sul thread principale, durante i quali l'interfaccia utente è bloccato, mentre metterla in un altro thread ed è praticamente immediato ! – siburb

+0

Devo salvare 40000 eventi e sto già usando la coda di sfondo, c'è un approccio performante per raggiungere questo obiettivo? – Mrug