2011-09-19 17 views
6

Ho un'app che si arresta in modo anomalo occasionalmente a causa dell'array restituito da ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering() di dimensioni diverse rispetto a ABAddressBookGetPersonCount(). La shell del codice è mostrata sotto. Di solito nPeople ha le stesse dimensioni dell'array. Tuttavia, sull'iPhone di un utente (o almeno, come riportato da un utente), nPeople è quasi due volte più grande. Posso fermare l'arresto utilizzando la dimensione dell'array, piuttosto che ABAddressBookGetPersonCount(). Tuttavia, non sono sicuro che ciò significhi che non accedo a tutti i Contatti nell'iPhone.ABAddressBookCopyArrayOfAllPeople e ABAddressBookGetPersonCount restituiscono diverse dimensioni

  • Qualcuno ha mai incontrato prima questo problema?
  • Perché i numeri dovrebbero essere diversi?

Mi chiedevo se fosse qualcosa a che fare con i contatti memorizzati in Gruppi (non so che ci sono gruppi - solo un'idea). Inoltre, dall'indirizzo email dell'utente, ho il sospetto che usino MobileMe. Mi chiedevo se la sincronizzazione con MobileMe creerebbe duplicati con un recordId differente, ma non eliminare il contatto esistente, almeno non fino a quando ABAddressBookGetPersonCount().

MODIFICA: Ho esaminato un po 'di più e ho una buona idea della causa del problema. Poiché volevo una serie ordinata di contatti, ho usato ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(). Ciò richiede una fonte della rubrica: ho usato la fonte predefinita. Credo che ci possano essere varie fonti: la fonte locale e altre come Exchange e MobileMe. Pertanto, il mio array finirà con solo i contatti locali, mentre il numero restituito da ABAddressBookGetPersonCount() includerà tutte le fonti - da qui il mio crash. Pertanto, penso che sarebbe meglio lavorare con i dati locali nella mia app e utilizzare la dimensione dell'array restituita da ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering piuttosto che da ABAddressBookGetPersonCount.

CFArrayRef allPeople = InSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName); 

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); 

    for (int i = 0; i < nPeople; i++) 
    { 
     ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i); 
    } 

risposta

13

ABAddressBookGetPersonCount E ABAddressBookCopyArrayOfAllPeople dà matrici diverse.

ABAddressBookGetPersonCount - Restituisce il numero di record di persone in una rubrica. ABAddressBookCopyArrayOfAllPeople - Restituisce tutti i record di persone in una rubrica.

Quindi alcune volte la stessa persona potrebbe avere record aggiuntivi. Ecco perché puoi ottenere diverse dimensioni.

+0

che significa che ABAddressBookGetPersonCount deve sempre essere inferiore a ABAddressBookCopyArrayOfAllPeople? –

+0

Dipende. Sarà diverso se la stessa persona potrebbe avere record extra. Se ogni persona ha un solo numero di contatto. Allora entrambi saranno uguali. :) @NikitaP –

9

Ho incontrato questo problema oggi. La mia app si arresta anche in alcuni iDevice speciali.

codice:

ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook); 
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName); 

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); 

    for (int i = 0; i < nPeople; i++) { 
     ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i); 
     // more thing with `person` 
    } 

Ma andrà in crash a volte. Aggiungendo alcuni punti di interruzione, ho trovato che il conteggio di allPeople è inferiore a nPeople.

Googling, ho trovato this article. Ho scoperto che forse c'è qualcosa di sbagliato con ABAddressBookCopyDefaultSource. Qui ho ottenuto la fonte di default , devo invece avere tutte le fonti.Codice

:

CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook); 

CFIndex sourceCount = CFArrayGetCount(sources); 

for (CFIndex i = 0; i < sourceCount; i++) { 
    ABRecordRef currentSource = CFArrayGetValueAtIndex(source, i); 
    int sourceType = [(__bridge NSNumber *)ABRecordCopyValue(currentSource, kABSourceTypeProperty) intValue]; 
    switch (sourceType) { 

     case kABSourceTypeCardDAV: 
      NSLog(@"kABSourceTypeCardDAV"); 
      break; 

     case kABSourceTypeCardDAVSearch: 
      NSLog(@"kABSourceTypeCardDAVSearch"); 
      break; 

     case kABSourceTypeExchange: 
      NSLog(@"kABSourceTypeExchange"); 
      break; 

     case kABSourceTypeExchangeGAL: 
      NSLog(@"kABSourceTypeExchangeGAL"); 
      break; 

     case kABSourceTypeLDAP: 
      NSLog(@"kABSourceTypeLDAP"); 
      break; 

     case kABSourceTypeLocal: 
      NSLog(@"kABSourceTypeLocal"); 
      break; 

     case kABSourceTypeMobileMe: 
      NSLog(@"kABSourceTypeMobileMe"); 
      break; 

     default: 
      break; 
    } 
    CFArrayRef allPeopleInSource = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, currentSource, kABPersonSortByLastName); 
    NSLog(@"Count of allPeopleInSource: %i", CFArrayGetCount(allPeopleInSource)); 
} 

Poi ho avuto

kABSourceTypeCardDAV 
    Count of allPeopleInSource: 7 

che significa che c'è una sola fonte e solo 7 record in quella fonte.

Ma nella mia rubrica, ho 79 contatti!

Poi ho fatto un errore. Ho superato il sources-ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering, proprio come questo:

CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, sources, kABPersonSortByLastName); 

Come molti membri in allPeople?

72 !!!

Esattamente il conteggio dei record che non si trovano in sources.

Ho passato un CFArrayRef a ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering come secondo parametro, che si aspetta un ABRecordRef. Cosa succede se passo nil?

Infine, ho ottenuto i codici:

CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByLastName); 

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); 

    for (int i = 0; i < nPeople; i++) { 
     ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i); 
     // more thing with `person` 
    } 

Ora posso ottenere tutti i contatti nella rubrica.

Funziona correttamente su tutti i miei dispositivi!

Mi dispiace molto per il mio povero inglese ...

Speriamo che, questa risposta può aiutare.

Nota: Ora non capisco che cosa è source in AddressBook esattamente, Qualcuno può aiutarmi?

+0

Buona risposta. A volte tutti i contatti nella tua rubrica potrebbero non essere di una fonte. Potrebbe essere da Facebook, gmails diversi ecc. Quindi se non si specifica una fonte si ottengono tutti i contatti. – Kaey

Problemi correlati