0

I'm doing some testing on AddressBook and though I can get the data I am looking for I'm curious about how it is delivered. Specifically CFDictionaryRef. When I cast this to a NSDictionary and log to console I just get a string value, not a key=value pair. If I try to log allKeys my test app breaks.

Here's the code snippet I'm using:

if ([contactName isEqualToString:ownerName]) { 

                    //get reference to  their email addresses
                    ABMultiValueRef contactEmails = ABRecordCopyValue(thisPerson, kABPersonEmailProperty);

                    //loop
                    for (NSUInteger e = 0; e < ABMultiValueGetCount(contactEmails); e++){

                        CFDictionaryRef thisPersonCFEmailDict = ABMultiValueCopyValueAtIndex(contactEmails, e);
                        NSDictionary* thisPersonEmailDict = (__bridge NSDictionary*)thisPersonCFEmailDict;

                        NSLog(@"%@", [thisPersonEmailDict allKeys]);

                    }

                }
PruitIgoe
  • 6,166
  • 16
  • 70
  • 137
  • 1
    What makes you think `ABMultiValueCopyValueAtIndex()` returns a `CFDictionaryRef`? It's documented as returning a `CFTypeRef`, which is the CoreFoundation equivalent of `id`. – Lily Ballard Feb 06 '13 at 19:08
  • Nothing, I'm in the learning curve stage of this and just seeing what I can do. I was looking at a couple of SO post on the topic and pulling some snippets to see what worked. Thanks for the answer, that clears up my confusion. – PruitIgoe Feb 06 '13 at 19:13

2 Answers2

1

You're assuming ABMultiValueCopyValueAtIndex() returns a CFDictionaryRef. It doesn't. It returns whatever value is appropriate for that multi-value, as evidenced by the CFTypeRef return value.

You can use ABMultiValueGetPropertyType() to find out what type of value a particular multi-value record has. If that returns kABDictionaryPropertyType then you know it's a dictionary, but in your case it's probably returning kABStringPropertyType. It could also return kABInvalidPropertyType, which may indicate that the multi-value contains different types. If so, you'll need to resort to using CFGetTypeID() to identify the type of value returned from ABMultiValueCopyValueAtIndex().

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
1

CFDictionaryRef is the Core Foundation counterpart of NSDictionary. Because NSDictionary and CFDictionary are “toll-free bridged,” you can substitute a CFDictionary object for a NSDictionary object in your code (with appropriate casting). Although they are corresponding types, CFDictionary and NSDictionary do not have identical interfaces or implementations, and you can sometimes do things with CFDictionary that you cannot easily do with NSDictionary. Toll-free bridging, means that you can use the same data type as the parameter to a Core Foundation function call or as the receiver of an Objective-C message.

Dhruv Goel
  • 2,715
  • 1
  • 17
  • 17