How can I get a list of all the properties of an ABRecordRef?
Asked Answered
C

2

10

I would like to obtain a list of all the properties of an ABPersonRef and ABGroupRef without having to use the iOS predefined keys of kABPersonFirstNameProperty, kABPersonLastNameProperty... I'm playing with the address book and I'd like to iterate over all values for a particular person. I know there are predefined keys but Apple could very well add new ones in the future so I'd like to do something like:

ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (int i = 0; i < [allPeople count]; ++i) {
    ABRecordRef person = [allPeople objectAtIndex:i];

    // This is the line that I can't figure out.
    NSArray *allProperties = (NSArray *)ABRecordCopyArrayOfAllProperties(person);
}

I know that I'll encounter multivalue items that I'll have to loop though later, but the goal is to obtain a list of keys that I can iterate over for the single value properties. I don't care what the returned class is, NSArray, NSDictionary... whatever.

I greatly appreciate any advice!

Cchaddie answered 3/8, 2011 at 17:9 Comment(0)
F
8

You can try the following:

With ARC:

NSDictionary* dictionaryRepresentationForABPerson(ABRecordRef person)
{
    NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];

    for ( int32_t propertyIndex = kABPersonFirstNameProperty; propertyIndex <= kABPersonSocialProfileProperty; propertyIndex ++ )
    {
        NSString* propertyName = CFBridgingRelease(ABPersonCopyLocalizedPropertyName(propertyIndex));
        id value = CFBridgingRelease(ABRecordCopyValue(person, propertyIndex));

        if ( value )
            [dictionary setObject:value forKey:propertyName];
    }

    return dictionary;
}
  • We using the localized name of the property - in different locales will have different keys.
  • The number of properties may change in the next version of iOS.

Maybe it makes sense to go through to the number of properties as long as the propertyName does not become UNKNOWN_PROPERTY

Frere answered 28/6, 2012 at 9:53 Comment(4)
Your code generates a complain from the analyzer: "Potential leak of an object stored into 'propertyName'" and "Potential leak of an object stored into 'value'" Any idea how to solve it?Tankage
Yes, I've moved all my projects to ARC.Tankage
Try to use CFBridgingRelease when casting.Frere
Can you please update the code, with the appropiate casting? I really dont know how to define it.Tankage
T
2

Aliaksandr's solution is not safe: for example if you attempt to create ABPerson records in a specific ABSource, and use this approach, you might find that contacts do not sync to that source properly.

I simply copied the list of 25 ABPropertyIDs from ABPerson, stuck them in a simple int[], and iterated over them...

        // Loop over all properties of this Person

        // taken from Apple's ABPerson reference page on 9.12.13.
        // URL: https://developer.apple.com/library/ios/documentation/AddressBook/Reference/ABPersonRef_iPhoneOS/Reference/reference.html#//apple_ref/c/func/ABPersonGetTypeOfProperty

        // count = 25. All are type ABPropertyID

        int propertyArray[25] = {
            kABPersonFirstNameProperty,
            kABPersonLastNameProperty,
            kABPersonMiddleNameProperty,
            kABPersonPrefixProperty,
            kABPersonSuffixProperty,
            kABPersonNicknameProperty,
            kABPersonFirstNamePhoneticProperty,
            kABPersonLastNamePhoneticProperty,
            kABPersonMiddleNamePhoneticProperty,
            kABPersonOrganizationProperty,
            kABPersonJobTitleProperty,
            kABPersonDepartmentProperty,
            kABPersonEmailProperty,
            kABPersonBirthdayProperty,
            kABPersonNoteProperty,
            kABPersonCreationDateProperty,
            kABPersonModificationDateProperty,

            kABPersonAddressProperty,
            kABPersonDateProperty,
            kABPersonKindProperty,
            kABPersonPhoneProperty,
            kABPersonInstantMessageProperty,
            kABPersonSocialProfileProperty,
            kABPersonURLProperty,
            kABPersonRelatedNamesProperty
        };
        int propertyArraySize = 25;



        for ( int propertyIndex = 0; propertyIndex < propertyArraySize; propertyIndex++ ) {
...code here
}                
Telegenic answered 9/12, 2013 at 12:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.