2013-11-22 1 views
4

Я пытаюсь получить выбранный номер мобильного телефона сpeoplePickerNavigationController: shouldContinueAfterSelectingPerson: Свойство: идентификатор:

ABMultiValueRef phones = ABRecordCopyValue(person, property); 
CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, identifier); 

У меня есть связь с несколькими мобильными телефонами (все меченый «мобильный»). Когда я выбираю первый, PHONENUMBER дает мне первую, но если выбрать любой подряд одну, PHONENUMBER дает мне предыдущий номер:

Контакт: Jay Jaymes мобильных +1111111111 мобильных +2222222222 мобильных +3333333333

Нажмите первый, phoneNumber = +1111111111

Нажмите второй, phoneNumber = +1111111111

Нажмите третий, phoneNumber = +2222222222

+0

Как вы их выбираете? Можете ли вы вставить код для этого? Это табличное представление и как вы сопоставляете их с ячейками. –

+0

Что такое "Телефоны"? –

+0

Grzegorz, см. Один из ответов. – user3003787

ответ

4

Это код, который я использую. И это даст правильный номер телефона только

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier { 

     if (property == kABPersonPhoneProperty) { 

      ABMultiValueRef phoneProperty = ABRecordCopyValue(person,property); 
      CFIndex peopleIndex = ABMultiValueGetIndexForIdentifier(property, identifier); 
      NSString *phone = (__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(phoneProperty, peopleIndex); 

      [self dismissModalViewControllerAnimated:YES]; 
     } 
    return NO; 
} 
+0

Это именно то, что я делаю. За исключением __bridge_transfer Я использую только __bridge, но я сомневаюсь, что что-то меняет. Он начал работать, как ожидалось (по крайней мере, на симуляторе) – user3003787

+1

@ user3003787 Если вы используете '__bridge_transfer', ARC позаботится об освобождении этого объекта для вас. Если вы используете '__bridge', вам придется вручную' CFRelease' объект, иначе вы будете течь. Если вы запустите свой код через статический анализатор («Проанализируйте» в меню «Продукт» Xcode), это довольно хорошо для определения таких проблем для вас. – Rob

+0

@Rob Это просто пример того, как получить номер телефона. Там может быть много случаев, в которых число ошибочно. В этом случае вы можете поместить некоторое «Регулярное выражение», чтобы проверить это. –

0

Вы можете легко повторить так. Попробуйте NSLoging этого кода, чтобы убедиться, что он работает. Я думаю, что у вас есть некоторые ошибки в вашей логике «выбора».

ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty); 

for (CFIndex i=0; i < ABMultiValueGetCount(phones); i++) 
{ 
    NSString* phoneLabel = (NSString*)ABMultiValueCopyLabelAtIndex(phones, i); 
    NSString* phoneNumber = ABMultiValueCopyValueAtIndex(phones, i); 

    //release variables since you were using COPY !!! 
    CFRelease(phoneNumber); 
    CFRelease(phoneLabel); 
} 

CFRelease(phones); 
0

Кончались реализующим это следующим образом:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier 
{ 
    if (property == kABPersonPhoneProperty) 
    { 
     ABMultiValueRef phones = ABRecordCopyValue(person, property); 
     CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, identifier); 
     NSLog(@"%@", phoneNumber); 
     NSMutableString *tmp = [NSMutableString stringWithFormat:@"%@", (__bridge_transfer NSString *)phoneNumber]; 
     NSString *strippedPhoneNumber = [tmp stringByReplacingOccurrencesOfString:@" " withString:@""]; 
     NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:@"()-"]; 
     strippedPhoneNumber = [[strippedPhoneNumber componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: @""]; 
     NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
     [peoplePicker dismissViewControllerAnimated:YES completion:nil]; 
     return NO; 
} 
+0

Две проблемы: во-первых, вы не должны использовать 'идентификатор' в' ABMultiValueCopyValueAtIndex'. Сначала вы должны получить индекс из идентификатора с помощью 'ABMultiValueGetIndexForIdentifier', а затем использовать этот' CFIndex' в 'ABMultiValueCopyValueAtIndex'. Во-вторых, вы не выполняете 'CFRelease (телефоны)', поэтому это будет протекать.Запустите это через статический анализатор («Проанализируйте» в меню «Продукт» Xcode), и это довольно хорошо при определении этих проблем. – Rob

0

Вы не должны использовать identifier в качестве индекса в ABMultiValueCopyValueAtIndex. Вы должны позвонить ABMultiValueGetIndexForIdentifier преобразовать ABMultiValueIdentifier идентификатор в CFIndex индекс:

ABMultiValueRef phones = ABRecordCopyValue(person, property); 
CFIndex index = ABMultiValueGetIndexForIdentifier(phones, identifier); 
NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, index)); 
CFRelease(phones); 

Как правило, ABMultiValueIdentifier значения соответствуют CFIndex значения, возвращаемые ABMultiValueGetIndexForIdentifier, но если контакт был отредактирован (в частности, если один из ранее телефонных номеров было удалено), используя ABMultiValueIdentifier в ABMultiValueCopyValueAtIndex, вернет неправильную запись.