Поля ABRecordRef не заполнены?

[фон: iOS 7, Xcode 5, оба обновленные по состоянию на февраль 2014 года. Тестовые данные - это записи адресной книги с несколькими телефонными номерами и несколькими адресами в дополнение к основной контактной информации на iPhone 5 (реальное устройство, а не симулятор)]

Моя цель - использовать методы AddressBookUI, чтобы пользователь мог указать контакт, а затем использовать различные поля (адреса, номера телефонов и т. Д.), Чтобы заполнить GUI в моем коде. ABPeoplePickerNavigationController это стандартный механизм, позволяющий пользователю выбрать контакт по имени. В результате этого вызывается метод делегата:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker 
shouldContinueAfterSelectingPerson:(ABRecordRef)person

Однако, если я проверю запись о человеке на этом этапе, ни одно из полей с несколькими значениями не содержит данных. Итак, я извлек RecordID, извлек это, и в результате ABRecordRef также не имеет заполненных полей с несколькими значениями.

Если я вернусь YES из метода делегата пользователю отображается другой пользовательский интерфейс с отображаемой контактной информацией. Прикосновение к любому полю приводит к вызову метода делегата

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

и это ABRecordRef заполнены все поля с несколькими значениями

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

Любые предложения о том, что может происходить, или как я могу получить полные записи без отображения второго пользовательского интерфейса для пользователя?

Я использую пример кода Apple QuickContacts. Вот дополнения и изменения, которые я сделал.

+(NSMutableDictionary *)convertABRecordRef:(ABRecordRef)person
{
    // Initialize a mutable dictionary and give it initial values.
    NSMutableDictionary *contactInfoDict = [[NSMutableDictionary alloc] initWithCapacity:12];

    // Use a general Core Foundation object.
    CFTypeRef generalCFObject = ABRecordCopyValue(person, kABPersonFirstNameProperty);

    ABRecordID foundId = ABRecordGetRecordID(person);
    NSNumber *personIDNum = [NSNumber numberWithInteger:foundId];
    [contactInfoDict setObject:personIDNum forKey:@"recordID"];


    // Get the first name.
    if (generalCFObject)
    {
        [contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"firstName"];
        CFRelease(generalCFObject);
    }

    // Get the last name.
    generalCFObject = ABRecordCopyValue(person, kABPersonLastNameProperty);
    if (generalCFObject) {
        [contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"lastName"];
        CFRelease(generalCFObject);
    }

    generalCFObject = ABRecordCopyValue(person, kABPersonOrganizationProperty);
    if (generalCFObject) {
        [contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"companyName"];
        CFRelease(generalCFObject);
    }

    //ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
    //NSArray *numbers = (NSArray *)ABMultiValueCopyArrayOfAllValues(phones);


    // Get the phone numbers as a multi-value property.
    ABMultiValueRef phonesRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
    CFIndex phoneCount = ABMultiValueGetCount(phonesRef);
    for (CFIndex i=0; i<ABMultiValueGetCount(phonesRef); i++) {

        CFStringRef currentPhoneLabel = ABMultiValueCopyLabelAtIndex(phonesRef, i);
        CFStringRef currentPhoneValue = ABMultiValueCopyValueAtIndex(phonesRef, i);

        if (CFStringCompare(currentPhoneLabel, kABPersonPhoneMobileLabel, 0) == kCFCompareEqualTo) {
            [contactInfoDict setObject:(__bridge NSString *)currentPhoneValue forKey:@"mobileNumber"];
        }

        if (CFStringCompare(currentPhoneLabel, kABHomeLabel, 0) == kCFCompareEqualTo) {
            [contactInfoDict setObject:(__bridge NSString *)currentPhoneValue forKey:@"homeNumber"];
        }

        if (CFStringCompare(currentPhoneLabel, kABWorkLabel, 0) == kCFCompareEqualTo) {
            [contactInfoDict setObject:(__bridge NSString *)currentPhoneValue forKey:@"workNumber"];
        }

        CFRelease(currentPhoneLabel);
        CFRelease(currentPhoneValue);
    }
    CFRelease(phonesRef);


    // Get the e-mail addresses as a multi-value property.
    ABMultiValueRef emailsRef = ABRecordCopyValue(person, kABPersonEmailProperty);
    for (int i=0; i<ABMultiValueGetCount(emailsRef); i++)
    {
        CFStringRef currentEmailLabel = ABMultiValueCopyLabelAtIndex(emailsRef, i);
        CFStringRef currentEmailValue = ABMultiValueCopyValueAtIndex(emailsRef, i);

        if (CFStringCompare(currentEmailLabel, kABHomeLabel, 0) == kCFCompareEqualTo) {
            [contactInfoDict setObject:(__bridge NSString *)currentEmailValue forKey:@"homeEmail"];
        }

        if (CFStringCompare(currentEmailLabel, kABWorkLabel, 0) == kCFCompareEqualTo) {
            [contactInfoDict setObject:(__bridge NSString *)currentEmailValue forKey:@"workEmail"];
        }

        CFRelease(currentEmailLabel);
        CFRelease(currentEmailValue);
    }
    CFRelease(emailsRef);


    // Get the first street address among all addresses of the selected contact.
    ABMultiValueRef addressRef =  ABRecordCopyValue(person, kABPersonAddressProperty);
    if (ABMultiValueGetCount(addressRef) > 0)
    {
        CFIndex numberOfAddresses = ABMultiValueGetCount(addressRef);
        for (CFIndex i=0; i<numberOfAddresses; i++)
        {
            CFStringRef label = ABMultiValueCopyLabelAtIndex(addressRef, i);
            if (label)
            {
                if (CFEqual(label, kABHomeLabel))
                {
                    NSDictionary *addressDict = (__bridge NSDictionary *)ABMultiValueCopyValueAtIndex(addressRef, 0);

                    [contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressStreetKey] forKey:@"homeAddress"];
                    [contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressZIPKey] forKey:@"homeZipCode"];
                    [contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressCityKey] forKey:@"homeCity"];

                }
                else if (CFEqual(label, kABWorkLabel))
                {
                    NSDictionary *addressDict = (__bridge NSDictionary *)ABMultiValueCopyValueAtIndex(addressRef, 0);

                    [contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressStreetKey] forKey:@"workAddress"];
                    [contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressZIPKey] forKey:@"workZipCode"];
                    [contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressCityKey] forKey:@"workCity"];
                }
                CFRelease(label);
            }
        }
    }
    CFRelease(addressRef);


    // If the contact has an image then get it too.
    if (ABPersonHasImageData(person)) {
        NSData *contactImageData = (__bridge NSData *)ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail);

        [contactInfoDict setObject:contactImageData forKey:@"image"];
    }


    return contactInfoDict;
}



// Displays the information of a selected person
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    // only returns a few fields, and none of the multi value ones  :-(
    NSMutableDictionary *results = [QuickContactsViewController convertABRecordRef:person];

    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    ABRecordID foundId = ABRecordGetRecordID(person);
    ABRecordRef fullPerson = ABAddressBookGetPersonWithRecordID(addressBook, foundId);

    // also only returns a few fields!?
    NSMutableDictionary *selectedFromID = [QuickContactsViewController convertABRecordRef:fullPerson];


    return YES;
}

// Does not allow users to perform default actions such as dialing a phone number, when they select a person property.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person 
                                property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    // returns all simple and multi-value fields!?   
    NSMutableDictionary *results = [QuickContactsViewController convertABRecordRef:person];

    return NO;
}

РЕДАКТИРОВАТЬ: Добавление моего решения (спасибо Торстен!).

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    NSArray *allPersonRecords = (NSArray *)CFBridgingRelease(ABPersonCopyArrayOfAllLinkedPeople(person));
    NSLog(@"Count Linked People: %i", allPersonRecords.count);

    NSMutableDictionary *results = [[NSMutableDictionary alloc]initWithCapacity:12];
    for (int x=0; x<[allPersonRecords count]; x++)
    {
        ABRecordRef user = CFBridgingRetain([allPersonRecords objectAtIndex:x]);
        NSMutableDictionary *userFromArray = [QuickContactsViewController convertABRecordRef:user];
        [results addEntriesFromDictionary:userFromArray];  // mush them together
        CFRelease(user);
    }

    NSLog(@"finished! Total number of contact fields found:%d", [results count]);
    // do something with the data here...

    return NO;
}

1 ответ

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

NSArray *people = (NSArray *)CFBridgingRelease(ABPersonCopyArrayOfAllLinkedPeople(person));
...
ABRecordRef user = CFBridgingRetain([people objectAtIndex:i]);
...
valuesRef = ABRecordCopyValue(user, kABPersonPhoneProperty);
valuesCount = 0;
if (valuesRef != nil) valuesCount = ABMultiValueGetCount(valuesRef);
...

НТН

Другие вопросы по тегам