Получите этикетку с номером телефона iPhone из адресной книги

Итак, у меня есть способ получить все контактные номера телефонов из адресной книги на iPhone, но есть ли способ получить метку номера телефона? Например, вы можете сделать это: введите описание изображения здесь

И я бы хотел изменить свой метод печати этикетки (например, iPhone / Home / mobile / и т. Д.).

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef all = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex n = ABAddressBookGetPersonCount(addressBook);

for( int i = 0 ; i < n ; i++ )
{
    ABRecordRef ref = CFArrayGetValueAtIndex(all, i);
    NSString *firstName = (NSString *)ABRecordCopyValue(ref, kABPersonFirstNameProperty);
    NSLog(@"Name %@", firstName);

    ABMultiValueRef *phones = ABRecordCopyValue(ref, kABPersonPhoneProperty);
    for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
    {
        NSString *phoneLabel = @""; // ???

        CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
        //CFRelease(phones);
        NSString *phoneNumber = (NSString *)phoneNumberRef;
        CFRelease(phoneNumberRef);
        NSLog(@"  - %@ (%@)", phoneNumber, phoneLabel);
        [phoneNumber release];
    }
}

person ingh.am    schedule 20.03.2011    source источник


Ответы (4)


Просто используйте -

ABMultiValueRef phones = ABRecordCopyValue(ref, kABPersonPhoneProperty);
for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
{
  CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
  CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(phones, j);
  NSString *phoneLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
  //CFRelease(phones);
  NSString *phoneNumber = (NSString *)phoneNumberRef;
  CFRelease(phoneNumberRef);
  CFRelease(locLabel);
  NSLog(@"  - %@ (%@)", phoneNumber, phoneLabel);
  [phoneNumber release];
}

ИЗМЕНИТЬ См. примечания к этому ответу о CFBridgingRelease и __bridge_transfer.

person shannoga    schedule 20.03.2011
comment
Вместо использования (NSString ) для преобразования в строку используйте (__bridge_transfer NSString). - person Dev2rights; 05.02.2013
comment
Вы также можете использовать id CFBridgingRelease( CFTypeRef ) и его дополнение CFTypeRef CFBridgingRetain( id ). - person devios1; 02.08.2013
comment
Также я почти уверен, что вы не хотите вызывать CFRelease на тех после вызова CFBridgingRelease (или __bridge_transfer), поскольку весь смысл этого заключается в передаче ответственности за выпуск на объект Objective-C. - person devios1; 02.08.2013
comment
Спасибо! Это мне помогло! :) - person Vladimir; 12.05.2014
comment
У вас есть идеи, как я могу исправить эту ошибку? error: cannot initialize a variable of type 'CFStringRef' (aka 'const __CFString *') with an rvalue of type 'CFTypeRef' (aka 'const void *') ...CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j); - person Fouad; 25.09.2014
comment
Разве после цикла for не пропадает CFRelease(phones);? - person newenglander; 02.04.2016

Если вы добавляете записи в адресную книгу, эти предопределенные константы могут быть тем, что вам нужно, kABPersonPhoneMobileLabel, kABPersonPhoneIPhoneLabel, которые определены в файле ABPerson.h.

person DawnSong    schedule 25.12.2015

следующее должно помочь:

NSArray* AccountEmailAddresses(void)
{
    NSMutableArray *emailAddresses = [NSMutableArray array];
    @try
    {
        Class MailComposeController = NSClassFromString(@"MailComposeController") ?: NSClassFromString(@"MFMailComposeController");
        NSArray *accountEmailAddresses = [MailComposeController performSelector:@selector(accountEmailAddresses)];
        for (id address in accountEmailAddresses)
        {
            if ([address isKindOfClass:[NSString class]])
                [emailAddresses addObject:address];
        }
    }
    @catch (NSException *e) {}

    return [NSArray arrayWithArray:emailAddresses];
}


ABRecordRef ABGetMe(ABAddressBookRef addressBook)
{
    ABRecordRef me = NULL;
    NSArray *accountEmailAddresses = AccountEmailAddresses();
    CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFIndex peopleCount = CFArrayGetCount(people);
    for (CFIndex i = 0; i < peopleCount; i++)
    {
        ABRecordRef record = CFArrayGetValueAtIndex(people, i);
        ABMultiValueRef emails = ABRecordCopyValue(record, kABPersonEmailProperty);
        if (emails)
        {
            CFIndex emailCount = ABMultiValueGetCount(emails);
            for (CFIndex j = 0; j < emailCount; j++)
            {
                CFStringRef email = ABMultiValueCopyValueAtIndex(emails, j);
                if (email)
                {
                    if ([accountEmailAddresses containsObject:(id)email])
                        me = record;

                    CFRelease(email);
                }
                if (me)
                    break;
            }
            CFRelease(emails);
        }
        if (me)
            break;
    }

    return me;
}
person reflog    schedule 20.03.2011
comment
какие? пользователь спросил о телефонных номерах, а не об адресах электронной почты - person lensovet; 07.09.2012

person    schedule
comment
если этот код работает с deutsch, то мобильный превращается в мобил! . Как я могу справиться с такими случаями? Я не могу проверить все строки - person BaSha; 17.11.2014
comment
В порядке. Создайте файл локализации в своем проекте для того языка, на котором вы хотите. В этом файле определите mobile = 'mpbiel'. Я модифицирую в соответствии с приведенным выше кодом. - person abhi; 04.12.2014
comment
На самом деле я решил проблему. Нам нужно сравнить локальную метку вместо локализованной метки - ›let locLabel: CFStringRef = ABMultiValueCopyLabelAtIndex (phones, numberIndex) .takeUnrehibitedValue () as CFStringRef; if (String (locLabel) == String (kABHomeLabel)) {} - person BaSha; 04.12.2014