Как вы получаете номер телефона человека из адресной книги?
Все, что я хочу сделать, это позволить пользователю выбрать номер из адресной книги. Я нашел код в этом вопросе:
Как получить номер телефона из контакта адресной книги (iphone sdk)
ABMultiValueRef container = ABRecordCopyValue(person, property);
CFStringRef contactData = ABMultiValueCopyValueAtIndex(container, identifier);
CFRelease(container);
NSString *contactString = [NSString stringWithString:(NSString *)contactData];
CFRelease(contactData);
Проблема в том, что во второй строке (при работе на устройстве 3.0) я получаю следующую ошибку:
Менеджеру аккаунта не удалось найти аккаунт с идентификатором MobileMe:rustyshelf
с последующим:
Программа получила сигнал: "EXC_BAD_ACCESS".
Это все внутри метода делегата выбора:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
Это только один из контактов в моей адресной книге, который синхронизирован с Mobile Me
Изменить: Я думаю, что это может быть ошибка с SDK, это происходит для некоторых из моих контактов, но не для других...
7 ответов
Аргумент "identifier" не содержит CFIndex записи, к которой был произведен прикосновение. Метод, который я использую, чтобы сказать, какой номер телефона выбран пользователем, это:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
if (property == kABPersonPhoneProperty) {
ABMultiValueRef multiPhones = ABRecordCopyValue(person, kABPersonPhoneProperty);
for(CFIndex i = 0; i < ABMultiValueGetCount(multiPhones); i++) {
if(identifier == ABMultiValueGetIdentifierAtIndex (multiPhones, i)) {
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(multiPhones, i);
CFRelease(multiPhones);
NSString *phoneNumber = (NSString *) phoneNumberRef;
CFRelease(phoneNumberRef);
txtPhoneNumber.text = [NSString stringWithFormat:@"%@", phoneNumber];
[phoneNumber release];
}
}
}
[self dismissModalViewControllerAnimated:YES];
return NO;
}
Если исходить из ответа JWD, вот более безопасная версия, которая использует встроенные константы и выбирает номер iphone вместо другого номера мобильного телефона...
ABMultiValueRef phones =(NSString*)ABRecordCopyValue(person, kABPersonPhoneProperty);
NSString* mobile=@"";
NSString* mobileLabel;
for(CFIndex i = 0; i < ABMultiValueGetCount(phones); i++) {
mobileLabel = (NSString*)ABMultiValueCopyLabelAtIndex(phones, i);
if([mobileLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel])
{
[mobile release] ;
mobile = (NSString*)ABMultiValueCopyValueAtIndex(phones, i);
}
else if ([mobileLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel])
{
[mobile release] ;
mobile = (NSString*)ABMultiValueCopyValueAtIndex(phones, i);
break ;
}
}
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
if (property == kABPersonPhoneProperty)
{
ABMultiValueRef numbers = ABRecordCopyValue(person, property);
NSString* targetNumber = (__bridge NSString *) ABMultiValueCopyValueAtIndex(numbers, ABMultiValueGetIndexForIdentifier(numbers, identifierForValue));
NSLog(@"%@", targetNumber);
}
return NO;
}
Я использовал этот вопрос, чтобы построить свое собственное решение. Код, который я публикую, не предназначен для ответа, просто для кого-то, кто может найти его полезным. Это простые шаги для получения собственности. Управление памятью исключено.
Я использую это, чтобы извлечь номер мобильного телефона из ABRecordRef/ Переменная "запись" - это ABRecordRef, для которого вы хотите номер телефона. Где у меня есть "", вы можете использовать другую строку тега телефона, чтобы найти другие типы телефонных номеров.
//Get mobile phone number
ABMultiValueRef phones =(NSString*)ABRecordCopyValue(record, kABPersonPhoneProperty);
NSString* mobile=@"";
NSString* mobileLabel;
for(CFIndex i = 0; i < ABMultiValueGetCount(phones); i++) {
mobileLabel = (NSString*)ABMultiValueCopyLabelAtIndex(phones, i);
if([mobileLabel isEqualToString:@"_$!<Mobile>!$_"]) {
mobile = (NSString*)ABMultiValueCopyValueAtIndex(phones, i);
}
}
Вы должны быть в состоянии сделать следующее:
ABMultiValueRef phoneNumbers = (ABMultiValueRef)ABRecordCopyValue(person, kABPersonPhoneProperty);
CFRelease(phoneNumbers);
NSString* phoneNumber = (NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
Конечно, это только даст вам первое число (потенциально) многих, связанных с выбранным вами человеком.
Уходя от ответа Дэна:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
if (property == kABPersonPhoneProperty) { // if tapped is equal to a phone property
CFStringRef cfnumber;
ABMultiValueRef numbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
for(CFIndex i = 0; i < ABMultiValueGetCount(numbers); i++) {
if(identifier == ABMultiValueGetIdentifierAtIndex (numbers, i)) { //if tapped number identifier is the same as identifier number tapped
cfnumber = ABMultiValueCopyValueAtIndex(numbers, i); // copy the number to CFSTRING number
}
}
NSString *number = [NSString stringWithFormat:@"%@",cfnumber];
CFRelease(cfnumber);
//do anything you want with the number
}
return NO;
}
Не могу сказать вам, если это лучший / правильный путь. Но я столкнулся с некоторыми ошибками, используя код Дэна... поэтому я решил поделиться им после выяснения этого. Все еще изучаю цель c.. ха-ха.. Надеюсь, что это помогает..
С уважением, Steve0hh
Вы также можете использовать этот "ABMultiValueGetIndexForIdentifier", как в этом коде:
ABPropertyType pt = ABPersonGetTypeOfProperty(property);
NSString *phoneNumber;
if ((pt & kABMultiValueMask) == kABMultiValueMask) {
ABMultiValueRef phoneProperty = ABRecordCopyValue(person,property);
CFIndex idx = ABMultiValueGetIndexForIdentifier(phoneProperty, identifier);
phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(phoneProperty,idx);
CFRelease(phoneProperty);
}