1

I'm not finding Apple's documentation very helpful for actually getting data with a people picker, and there doesn't seem to be much other information on the internet :( I assume I need to get the email in this function:

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

}

What can I put in there to get the email of the selected person?

Randall
  • 2,083
  • 2
  • 18
  • 20

2 Answers2

4

Kal answer is actually inaccurate - namely because "ABMultiValueCopyValueAtIndex" takes an index not identifier.

Identifier value is static (like enumeration)

  • "Home Email" is always "0"
  • "Work Email" is always "1".

So it will crash when the person selected only have 1 email stored, which is a "Work Email". Since the identifier is "1", but we need index "0".

Luckily we can use following to get the index:

int index = ABMultiValueGetIndexForIdentifier(emails, identifier);

Code:

if (property == kABPersonEmailProperty) {

    ABMultiValueRef emails = ABRecordCopyValue(person, property);

    NSString *count = [NSString stringWithFormat:@"Count: %d Identifier: %d", ABMultiValueGetCount(emails), identifier];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"alert" message:count delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

    if(ABMultiValueGetCount(emails) > 0)
    {
        int index = ABMultiValueGetIndexForIdentifier(emails, identifier);
        CFStringRef emailTypeSelected = ABMultiValueCopyLabelAtIndex(emails, index);
        CFStringRef emailTypeSelectedLocalized = ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(emails, index));
        CFStringRef emailValueSelected = ABMultiValueCopyValueAtIndex(emails, index);

        self.lblEmailType.text = (NSString *) emailTypeSelected;
        self.lblEmailTypeLocalized.text = (NSString *) emailTypeSelectedLocalized;
        self.lblEmailValue.text = (NSString *) emailValueSelected;
    }

    [ self dismissModalViewControllerAnimated:YES ];
    return NO;
}

return YES;
friend
  • 1,909
  • 2
  • 21
  • 28
  • You should probably be releasing those CFRefs you're creating. As far as I know, "Copy" in the name of the called function means you have ownership of the returned object. See [this answer](http://stackoverflow.com/questions/4991564/potential-memory-leak-for-abrecordcopyvalue) – entropy Sep 18 '13 at 08:55
  • Or do this to give ARC control over the releases: (NSString*)CFBridgingRelease(ABMultiValueCopyLabelAtIndex(emails, index)) Fix the release issue und it's definitely the better answer. – marsbear Aug 13 '15 at 19:25
0

Use

ABMultiValueRef emails = ABRecordCopyValue(record, kABPersonEmailProperty);

After that, you can use the ABMultiValueRefs API method calls to get email address.

EDIT -- This should give you email

CFStringRef emailId = ABMultiValueCopyValueAtIndex(emails, identifier);
Kal
  • 24,724
  • 7
  • 65
  • 65
  • What method calls? I'm using the line you posted, but no method calls pop up when I type [emails – Randall Jul 18 '11 at 17:59
  • Nevermind, I did CFStringRef str = ABMultiValueCopyValueAtIndex(emails, 0); and that worked – Randall Jul 18 '11 at 18:03
  • @Randall: if you call it like that (with a fixed index 0) and there are no emails your app will crash. – Zebs Jul 18 '11 at 18:25
  • It would be a good idea to check that you got a value in emails first with if (ABMultiValueGetCount(emails) > 0) { – jj0b Nov 23 '11 at 20:18
  • This answer is actually inaccurate - "identifier" is not "index". See my answer. – friend Mar 30 '12 at 03:59