Search code examples
iosobjective-cabaddressbookpeoplepicker

Address Book - Select email of Linked contact


I am trying to fetch selected email property in delegate callback mentioned below

-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
        if (property==kABPersonEmailProperty) {
            ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
            if (ABMultiValueGetCount(emails) > 0) {
                NSString *email = (__bridge_transfer NSString*)
                ABMultiValueCopyValueAtIndex(emails, ABMultiValueGetIndexForIdentifier(emails,identifier));
                [recipientEmail setText:email];
                [peoplePicker dismissViewControllerAnimated:YES completion:nil];
            }
             CFRelease(emails);
        }
        return NO;
    }

But If I select the email property of linked contact (Having single email) I get the identifier as 0, as a result I get the first email-id of primary contact. Eg: John - [email protected] [email protected] Roger (Linked Contact) - [email protected]

When I select [email protected] I get [email protected].


Solution

  • I have this same issue. I get the wrong email when I select accounts with multiple email addresses. When I loop through the selected ABMutableMultiValueRef...

    for (CFIndex ix = 0; ix < ABMultiValueGetCount(emails); ix++) {
       CFStringRef label = ABMultiValueCopyLabelAtIndex(emails, ix);
       CFStringRef value = ABMultiValueCopyValueAtIndex(emails, ix);
       NSLog(@"I have a %@ address: %@", label, value);
       if (label) CFRelease(label);
       if (value) CFRelease(value);
    }
    

    ... I get multiple occurrences of the same address, but some with null labels.

    > I have a (null) address: [email protected]
    > I have a _$!<Work>!$_ address: [email protected]
    > I have a _$!<Home>!$_ address: [email protected]
    

    The workaround I will try is to filter out the null labels first, see if the ABMultiValueIdentifier 'fits', and if not revert to the null labels. Unless you have found something?

    Edit: this works for me.

        NSMutableArray *labeled = [NSMutableArray new];
        ABMutableMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
        for (CFIndex ix = 0; ix < ABMultiValueGetCount(emails); ix++) {
            CFStringRef label = ABMultiValueCopyLabelAtIndex(emails, ix);
            CFStringRef value = ABMultiValueCopyValueAtIndex(emails, ix);
            if (label != NULL) {
                [labeled addObject:(NSString *)CFBridgingRelease(value)];
            }
            if (label) CFRelease(label);
            if (value) CFRelease(value);
        }
        NSString *email;
        if (labeled.count > identifier) {
            email = [labeled objectAtIndex:identifier];
        } else {
            CFStringRef emailRef = ABMultiValueCopyValueAtIndex(emails, identifier);
            email = (NSString *)CFBridgingRelease(emailRef);
        }