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
- ABAddressBookCreate() устарел. Объявите ссылку в интерфейсе:
- Также удалите:
addressBook = ABAddressBookCreate();
- Также удалите:
- Обновите объявление sourceTypeRef & sourceTypeName:
Измените вызов метода 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));