ABAddressBookCopyArrayOfAllPeople и ABAddressBookGetPersonCount возвращают разные размеры - PullRequest
6 голосов
/ 19 сентября 2011

У меня есть приложение, которое иногда дает сбой из-за массива, возвращенного ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering (), размер которого отличается от размера ABAddressBookGetPersonCount (). Оболочка кода показана ниже. Обычно nPeople имеет тот же размер, что и массив. Однако на iPhone одного пользователя (или, по крайней мере, по сообщениям одного пользователя) nPeople почти в два раза больше. Я могу остановить сбой, используя размер массива, а не ABAddressBookGetPersonCount (). Однако я не уверен, означает ли это, что у меня нет доступа ко всем контактам на iPhone.

  • Кто-нибудь сталкивался с этой проблемой раньше?
  • Почему цифры были бы разными?

Я задавался вопросом, было ли это как-то связано с контактами, которые хранятся в группах (я не знаю, что есть группы - просто идея). Кроме того, с адреса электронной почты пользователя, я подозреваю, что они используют MobileMe. Мне было интересно, создаст ли синхронизация с MobileMe дубликаты с другим recordId, но не удалит существующий контакт, по крайней мере, не так далеко, как ABAddressBookGetPersonCount ().

EDIT: Я рассмотрел это еще немного и довольно неплохо понял причину проблемы. Поскольку я хотел отсортированный массив контактов, я использовал ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering (). Это требует источника адресной книги - я использовал источник по умолчанию. Я считаю, что могут быть различные источники - локальный источник плюс другие, такие как Exchange и MobileMe. Поэтому мой массив будет содержать только локальные контакты, тогда как число, возвращаемое ABAddressBookGetPersonCount (), будет включать все источники - отсюда мой сбой. Поэтому я думаю, что было бы лучше просто работать с локальными данными в моем приложении и использовать размер массива, возвращенный ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering, а не ABAddressBookGetPersonCount.

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

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

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

Ответы [ 3 ]

13 голосов
/ 24 февраля 2012

ABAddressBookGetPersonCount И ABAddressBookCopyArrayOfAllPeople предоставляет различные массивы.

ABAddressBookGetPersonCount - возвращает количество записей о персонах в адресной книге.ABAddressBookCopyArrayOfAllPeople - возвращает все записи о людях в адресной книге.

Так что иногда у одного и того же человека могут быть дополнительные записи.Вот почему вы можете получить разные размеры.

9 голосов
/ 21 апреля 2014

Я встречаюсь с этой проблемой сегодня. Мое приложение также зависает в некоторых специальных устройствах.

код:

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

Но иногда он падает. Добавляя некоторые точки останова, я обнаружил, что число allPeople меньше nPeople.

По поиску, я нашел эту статью . Я обнаружил, что, возможно, что-то не так с ABAddressBookCopyDefaultSource. Здесь у меня есть источник по умолчанию , вместо этого я должен получить все источники .

код:

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

Тогда я получил

    kABSourceTypeCardDAV
    Count of allPeopleInSource: 7

, что означает, что есть только один источник и только 7 записей в этом источнике.

Но в моей адресной книге у меня 79 контактов!

Тогда я допустил ошибку. Я передал sources на ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering, вот так:

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

Сколько членов в allPeople?

72 !!!

Точное количество записей, которых нет в sources.

Я передал CFArrayRef в ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering в качестве второго параметра, который ожидает ABRecordRef. Что если я пройду nil?

Наконец я получил коды:

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

Теперь я могу получить все контакты в моей адресной книге.

Отлично работает на всех моих iDevices!

Я очень сожалею о своем плохом английском ...

Надеюсь, этот ответ поможет вам.

Примечание : Теперь я не понимаю, что такое source в AddressBook, кто-нибудь может мне помочь?

3 голосов
/ 12 мая 2015

@ Jokinryou Tsui Передача источника, поскольку ноль был ключом, спасибо!Похоже, что типы источников могут соответствовать этой документации от Apple: https://developer.apple.com/library/ios/documentation/AddressBook/Reference/ABSourceRef_iPhoneOS/#//apple_ref/doc/constant_group/Source_Types

...