Я показываю пользователю адресную книгу и позволяю ему щелкнуть контакт и выбрать номер телефона. Если они выберут номер телефона, я хочу получить номер телефона как целое число, а имя контакта как NSString.
Я пробовал сделать это с помощью следующего кода:
//printf("%s\n",[[(NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty) objectAtIndex:identifier] UTF8String]);
//CFArrayRef *arrayString = [[(NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty) objectAtIndex:identifier] UTF8String];
NSArray *arrayString = [(NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty) objectAtIndex:identifier];
printf("%s\n", arrayString);
Этот код находится внутри этого метода:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
И я проверяю, выбрал ли пользователь номер телефона с этим кодом:
if (propertyType == kABStringPropertyType)
{
[self wrongSelection];
}
else if (propertyType == kABIntegerPropertyType)
{
[self wrongSelection];
}
else if (propertyType == kABRealPropertyType)
{
[self wrongSelection];
}
else if (propertyType == kABMultiStringPropertyType)
{
//This is the phone number...
Я могу получить номер телефона для отображения в консоли с помощью printf, однако я не могу понять, как преобразовать его в целое число и как также получить имя контакта, даже если выбранное свойство не является именем человека.
Кроме того, то, что я делаю, кажется очень неэффективным. Есть ли лучшие способы сделать это?
Обновлено: если я не могу сохранить их как int, строка будет в порядке. Я просто не могу понять, как перейти от этого массива к реальной строке. Если я использую его или сохраняю как UTF8String, я всегда получаю некоторую ошибку.





Вы не можете преобразовать номер телефона в целое число. Телефонные номера представляют собой строки. Запись по умолчанию, которую Apple включает для себя, имеет номер «1-800-MYAPPLE».
Кроме того, даже если все компоненты телефонного номера являются цифрами, нет гарантии, что номера телефонов во всех частях мира на самом деле достаточно малы, чтобы поместиться в 64-битное значение, если вы учитываете коды городов, коды стран и внутренние добавочные номера. и т. д. Пользователи могут помещать туда столько, сколько захотят.
Чтобы получить свойство эффективно (что касается чтения), вы можете сделать что-то вроде этого в своем методе обратного вызова:
switch( propertyType ) {
case kABMultiStringPropertyType:
// this is the phone number, do something
break;
default:
[self wrongSelection];
break;
}
Я не уверен, что вам вообще нужно это разбирать. Чтобы получить номер телефона из записи, вы можете сделать (опять же, внутри вашего метода обратного вызова):
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSArray* phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty);
CFRelease(phoneNUmberProperty);
// Do whatever you want with the phone numbers
NSLog(@"Phone numbers = %@", phoneNumbers);
[phoneNumbers release];
Я знаю, что опаздываю на игру, но я только что наткнулся на этот вопрос. Я делаю следующее: ABMutableMultiValueRef multi; int multiCount=0; multi = ABRecordCopyValue(person, kABPersonPhoneProperty); multiCount=ABMultiValueGetCount(multi); for( int i=0; i < multiCount; i++) { NSString *descriptionString = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(multi, i); NSString *theNumber = (__bridge NSString*)ABMultiValueCopyValueAtIndex(multi, i); } Где descriptionString будет выглядеть примерно как $! <Мобильный>! $
Это утечки. Вы должны использовать NSArray *phoneNumbers = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(phoneNumberProperty));
CFStringRef cfName = ABRecordCopyCompositeName(person);
NSString *personName = [NSString stringWithString:(NSString *)cfName];
CFRelease(cfName);
ABMultiValueRef container = ABRecordCopyValue(person, property);
CFStringRef contactData = ABMultiValueCopyValueAtIndex(container, identifier);
CFRelease(container);
NSString *contactString = [NSString stringWithString:(NSString *)contactData];
CFRelease(contactData);
contactString содержит выбранный номер телефона, а personName содержит имя человека. Как указано выше, вы не можете обязательно преобразовать строку в числа в целом, так как она может содержать буквенные символы. Однако вы можете написать свой собственный обработчик для преобразования буквенных символов в числа и вырезать все остальное, чтобы получить только числовую строку, которую затем можно преобразовать в длинную (номера телефонов становятся довольно длинными).
Я сомневаюсь в необходимости преобразования номера телефона в числовое значение, поскольку он также может содержать другие необходимые символы, такие как пауза. Кроме того, номер телефона в любом случае представляет собой строку цифр больше, чем один длинный номер, поэтому концептуальный формат данных в любом случае больше String, чем Int.
Просто столкнулся с проблемой с этим кодом. ABMultiValueCopyValueAtIndex (контейнер, идентификатор) ожидает индекс, а не идентификатор. Это будет периодически сбоить. Код должен быть ABMultiValueCopyValueAtIndex (контейнер, ABMultiValueGetIndexForIdentifier (контейнер, идентификатор)). См. Это сообщение на форуме: форумы.macrumors.com/showthread.php?t=705504
Еще одна причина не использовать целые числа - в некоторых странах в телефонных номерах используются ведущие нули, например все британские номера начинаются с нуля (обычно пишется 01234 567890 или 0123 4567890)!
Имейте в виду, что этот код вылетает в "stringWithString", если Adressbook-Entry не содержит имени или контактных данных. cfName может быть нулевым!
CFStringRef cfName = ABRecordCopyCompositeName(person);
NSString *personName = [NSString stringWithString:(NSString *)cfName];
CFRelease(cfName);
исправить:
NSString *personName = nil;
if ((cfName = ABRecordCopyCompositeName(person)) != nil) {
personName = [NSString stringWithString:(NSString *)cfName];
CFRelease(cfName);
}
Или сейчас просто NSString *personName = CFBridgingRelease(ABRecordCopyCompositeName(person));
Привет, Джейсон, спасибо за ответ. Я считаю, что есть опечатка с "phoneNUmberProperty" (должно быть "phoneNumberProperty"). Быстрый вопрос: как получить тип, связанный с номером телефона (например, мобильный, iPhone, домашний)?