Как вы получаете номер телефона человека из адресной книги? - PullRequest
22 голосов
/ 13 июля 2009

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

Как получить номер телефона из контакта адресной книги (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 ]

29 голосов
/ 31 июля 2009

Аргумент «идентификатора» не содержит 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;
}
16 голосов
/ 10 августа 2009

Если исходить из ответа 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 ;
    }
}
6 голосов
/ 17 августа 2012
- (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;
}

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

4 голосов
/ 13 июля 2009

Я использую это, чтобы извлечь номер мобильного телефона из ABRecordRef / Переменная «record» - это 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);
    }
}
3 голосов
/ 13 июля 2009

Вы должны быть в состоянии сделать следующее:

ABMultiValueRef phoneNumbers = (ABMultiValueRef)ABRecordCopyValue(person, kABPersonPhoneProperty);
CFRelease(phoneNumbers);
NSString* phoneNumber = (NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, 0);

Конечно, это даст вам только первое число (потенциально) многих, связанных с выбранным человеком.

1 голос
/ 05 ноября 2011

Исходя из ответа Дэна:

- (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

1 голос
/ 03 октября 2011

вы также можете использовать этот «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);
    } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...