2011-09-19 23 views
6

Mam aplikację, która czasami się zawiesza z powodu tablicy zwróconej przez ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering() o innym rozmiarze niż ABAddressBookGetPersonCount(). Powłoka kodu jest pokazana poniżej. Zazwyczaj nPeople ma taki sam rozmiar jak tablica. Jednak na iPhonie jednego użytkownika (lub przynajmniej według jednego użytkownika) nPeople jest prawie dwa razy większy. Mogę zatrzymać awarię za pomocą rozmiaru tablicy, a nie ABAddressBookGetPersonCount(). Jednak nie jestem pewien, czy oznacza to, że nie mam dostępu do wszystkich kontaktów w telefonie iPhone.ABAddressBookCopyArrayOfAllPeople i ABAddressBookGetPersonCount zwracają różne rozmiary

  • Czy ktoś już wcześniej napotkał ten problem?
  • Dlaczego liczby byłyby różne?

Zastanawiałem się, czy miało to coś wspólnego z kontaktami przechowywanymi w Grupach (nie wiem, czy istnieją grupy - po prostu pomysł). Również z adresu e-mail użytkownika podejrzewam, że używają MobileMe. Zastanawiałem się, czy synchronizacja z MobileMe spowoduje utworzenie duplikatów z innym rekordem, ale nie usunie istniejącego kontaktu, przynajmniej jeśli chodzi o ABAddressBookGetPersonCount().

EDYCJA: Zajrzałem do tego więcej i mam dość dobry pomysł na przyczynę problemu. Ponieważ chciałem posortowane tablice kontaktów, użyłem ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(). Wymaga to źródła książki adresowej - użyłem domyślnego źródła. Wierzę, że mogą istnieć różne źródła - lokalne źródła i inne, takie jak Exchange i MobileMe. W związku z tym moja tablica będzie zawierała tylko lokalne kontakty, podczas gdy liczba zwrócona przez ABAddressBookGetPersonCount() będzie zawierać wszystkie źródła - stąd moja awaria. Dlatego uważam, że lepiej byłoby po prostu pracować z lokalnymi danymi w mojej aplikacji i użyć rozmiaru tablicy zwróconego przez ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering zamiast ABAddressBookGetPersonCount.

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

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook); 

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

Odpowiedz

13

ABAddressBookGetPersonCount I ABAddressBookCopyArrayOfAllPeople daje różne tablice.

ABAddressBookGetPersonCount - Zwraca liczbę rekordów osób w książce adresowej. ABAddressBookCopyArrayOfAllPeople - zwraca wszystkie wpisy osób w książce adresowej.

Niektóre osoby mogą mieć dodatkowe rekordy. Dlatego możesz uzyskać różne rozmiary.

+0

oznacza to, że ABAddressBookGetPersonCount powinien być zawsze mniejszy niż ABAddressBookCopyArrayOfAllPeople? –

+0

To zależy. Będzie inaczej, jeśli ta sama osoba może mieć dodatkowe rekordy. Jeśli każda osoba ma jeden numer kontaktowy. Wtedy oba będą takie same. :) @NikitaP –

9

Dziś napotykam ten problem. Moja aplikacja również zawiesza się w niektórych specjalnych urządzeniach.

Kod:

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` 
    } 

Ale to awarię czasami. Dodając kilka punktów przerwania stwierdziłem, że liczba allPeople jest mniejsza niż nPeople.

W googlowaniu znalazłem this article. Odkryłem, że być może coś jest nie tak z ABAddressBookCopyDefaultSource. Tutaj mam domyślne źródło , zamiast tego muszę uzyskać wszystkie źródła.Kod

:

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

Potem dostałem

kABSourceTypeCardDAV 
    Count of allPeopleInSource: 7 

co oznacza, że ​​jest tylko jedno źródło, a tylko 7 rekordy w tym źródle.

Ale w mojej książce adresowej mam 79 kontaktów!

Potem popełniłem błąd. Zdałem sources do ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering, podobnie jak to:

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

Ilu członków w allPeople?

72 !!!

Dokładna liczba rekordów, których nie ma w stanie sources.

Podałem CFArrayRef do ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering jako drugi parametr, który oczekuje ABRecordRef. Co się stanie, jeśli przejdę nil?

Wreszcie mam kody:

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` 
    } 

Teraz mogę uzyskać wszystkich kontaktów w książce adresowej.

Działa dobrze na wszystkich moich iDevices!

Bardzo przepraszam za mój słaby angielski ...

Mamy nadzieję, że ta odpowiedź może pomóc.

Uwaga: Teraz ja nie rozumiem, co jest source w AddressBook dokładnie, Czy ktoś może mi pomóc?

+0

Dobra odpowiedź. Czasami wszystkie kontakty w książce adresowej mogą nie pochodzić z jednego źródła. Może pochodzić z Facebooka, różnych serwisów społecznościowych itp. Jeśli nie podasz źródła, otrzymasz wszystkie kontakty. – Kaey