ABAddressBook ABSource и ABSourceType

Я пытаюсь создать приложение, которое можно использовать для поиска в Exchange GAL, однако я нахожу новую документацию 4.0 по этому вопросу неясной. Кто-нибудь знает, как я могу искать в GAL имена, содержащие определенную строку (например, "Smi")? Мой исходный код на данный момент практически бесполезен, так как я просто пытаюсь обернуть голову, как указать, что я хочу только искать GAL, а не локальные контакты на устройстве. Кроме того, как используется kABSourceTypeSearchableMask? Я упускаю что-то фундаментальное здесь. Из документации...

Типы источников

Эти константы определяют тип источника.

enum {
    kABSourceTypeLocal       = 0x0,
    kABSourceTypeExchange    = 0x1,
    kABSourceTypeExchangeGAL = kABSourceTypeExchange | kABSourceTypeSearchableMask,
    kABSourceTypeMobileMe    = 0x2,
    kABSourceTypeLDAP        = 0x3 | kABSourceTypeSearchableMask,
    kABSourceTypeCardDAV     = 0x4,
    kABSourceTypeCardDAVSearch = kABSourceTypeCardDAV | kABSourceTypeSearchableMask,
};
typedef int ABSourceType;

Когда я запрашиваю тип источника по умолчанию, я получаю "1", который, по-видимому, указывает на то, что типом по умолчанию является "kABSourceTypeExchange", что будет правильным, так как это то, что я имею в своих настройках. Я не знаю, как выйти за рамки этого пункта...

Поскольку вся концепция исходного кода является новой для фреймворка ABAddressBook в 4.0, я не думаю, что у людей есть большой опыт с этим, но надеюсь, что кто-то может помочь мне понять, как работать с вышеизложенным... спасибо.

3 ответа

Чтобы получить доступ к Exchange GAL, вам нужно использовать функцию ABAddressBookCopyArrayOfAllSources, чтобы получить массив всех источников, а затем выполнить итерацию по массиву, чтобы попытаться получить правильный источник для Exchange GAL. Используйте функцию ABRecordCopyValue(), чтобы получить свойство kABSourceTypeProperty источника.

например

ABRecordRef searchableExchangeSource;

addressBook = ABAddressBookCreate();
CFArrayRef allSources = ABAddressBookCopyArrayOfAllSources(addressBook);
for (CFIndex i = 0; i < CFArrayGetCount(allSources); i++) {
    ABRecordRef source = (ABRecordRef)CFArrayGetValueAtIndex(allSources, i);

    // Get source properties
    NSNumber *sourceTypeRef = (NSNumber *)((CFNumberRef)ABRecordCopyValue(source, kABSourceTypeProperty));
    NSString *sourceTypeName = (NSString *)((CFStringRef)ABRecordCopyValue(source, kABSourceNameProperty));
    int sourceType = [sourceTypeRef intValue];
    NSLog(@"Found Source Type: %@ with ABSourceType %i", sourceTypeName,sourceType);
    if (sourceType == kABSourceTypeExchangeGAL) {
        searchableExchangeSource = source;
    }
    [sourceTypeRef release];
    [sourceTypeName release];
}

Обратите внимание, что если у вас настроено несколько учетных записей "Exchange", вы получите несколько источников с одинаковым ABSourceType. К сожалению, из моего ограниченного тестирования, kABSourceTypeNameProperty для GAL Exchange имеет значение NULL, поэтому вы не можете использовать это свойство для различения нескольких источников GAL Exchange.

Когда у вас есть соответствующий источник, он имеет тип ABRecordRef, поэтому вы можете взаимодействовать с ним, как и с любой другой записью.

Я разместил некоторый код здесь: Получение конкретного ABSource от ABAddressBook в iOS 4+

для выявления конкретных источников. Это может быть полезно, чтобы помочь вам увидеть, как работать с ABAddressBook.

Обновление для ответа Mixja

  1. ABAddressBookCreate() устарел. Объявите ссылку в интерфейсе:
    • Также удалите: addressBook = ABAddressBookCreate();
  2. Обновите объявление sourceTypeRef & sourceTypeName:
  3. Измените вызов метода release на:

    // 1.
    @property(nonatomic, assign) ABAddressBookRef *addressBook;
    // 2.
    NSNumber *sourceTypeRef = (__bridge NSNumber *)((CFNumberRef)ABRecordCopyValue(source, kABSourceTypeProperty));
    NSString *sourceTypeName = (__bridge NSString *)((CFStringRef)ABRecordCopyValue(source, kABSourceNameProperty));
    
    // 3.
    CFRelease((__bridge CFTypeRef)(sourceTypeRef));
    CFRelease((__bridge CFTypeRef)(sourceTypeName));
    

Конечный код должен выглядеть примерно так:

Обязательно включите шаг 1!

    ABRecordRef searchableExchangeSource;

    CFArrayRef allSources = ABAddressBookCopyArrayOfAllSources(_addressBook);
    for (CFIndex i = 0; i < CFArrayGetCount(allSources); i++) {
    ABRecordRef source = (ABRecordRef)CFArrayGetValueAtIndex(allSources, i);

    // Get source properties
    NSNumber *sourceTypeRef = (__bridge NSNumber *)((CFNumberRef)ABRecordCopyValue(source, kABSourceTypeProperty));
    NSString *sourceTypeName = (__bridge NSString *)((CFStringRef)ABRecordCopyValue(source, kABSourceNameProperty));
    int sourceType = [sourceTypeRef intValue];
    NSLog(@"Found Source Type: %@ with ABSourceType %i", sourceTypeName,sourceType);
    if (sourceType == kABSourceTypeExchangeGAL) {
        searchableExchangeSource = source;
    }
    CFRelease((__bridge CFTypeRef)(sourceTypeRef));
    CFRelease((__bridge CFTypeRef)(sourceTypeName));
Другие вопросы по тегам