2

What I'm trying to do is show the people picker to the user, make him select all the contacts he wants, and finally get all those contacts' email addresses in an array. The best would be showing only contacts with email to the user.

Until now the only thing I've been able to do is presenting the people picker with this code:

ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
     picker.peoplePickerDelegate = self;
     [self presentModalViewController:picker animated:YES];

Then I was trying to use this code to get the selected contacts' email:

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

ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonEmailProperty);
[email addObject:(__bridge NSString*)ABMultiValueCopyValueAtIndex(multi, 0)];
[self dismissModalViewControllerAnimated:YES];

return YES;
}

But the picker is going away as soon as I select a contact, so I don't know how to continue. Moreover, right when I select a contact I get this in the console:

"Unbalanced calls to begin/end appearance transitions for 
<ABMembersViewController: 0xa1618c0>."

Any help would be appreciated.

Aleph72
  • 877
  • 1
  • 13
  • 40
  • I don't believe that you can have `ABPeoplePickerNavigationController` only show contacts with email addresses, but effective iOS 8, you can have it disable (i.e. gray out) those contacts without email addresses. If you want to show only those with email addresses, you can build an array of those with email addresses (and [shown here](http://stackoverflow.com/a/25254013/1271826)) and then show in that list in your own table view. – Rob Aug 12 '14 at 15:45

2 Answers2

7

I am not sure if you ever solved your problem but if anyone else finds this post maybe it will help them. What I did to get an email from the ABPeoplePickerNavigationController was to remove

[self dismissModalViewControllerAnimated:YES];

from

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

and then I am using this to get the email and dismiss the controller

- (BOOL)peoplePickerNavigationController(ABPeoplePickerNavigationController*)peoplePicker
  shouldContinueAfterSelectingPerson:(ABRecordRef)person
                            property:(ABPropertyID)property
                          identifier:(ABMultiValueIdentifier)identifier
{
    if (kABPersonEmailProperty == property)
    {
        ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonEmailProperty);
        NSString *email = (__bridge NSString *)ABMultiValueCopyValueAtIndex(multi, 0);
        NSLog(@"email: %@", email);
        [self dismissModalViewControllerAnimated:YES];
        return NO;
    }
    return YES;
}

It allows the user to select a specific email and dismisses the controller without any errors.

Jeff B
  • 223
  • 1
  • 3
  • 12
  • Thanks Jeff, at the end I did something like the code you posted, but I forgot to post the answer. – Aleph72 Nov 01 '12 at 10:06
3

As far as I can tell, this won't actually give you the email address that was selected. If a contact has "home" and "work" emails then ABMultiValueCopyValueAtIndex(multi, 0) will just give you the "home" email.

You need to get the index for the selected email from the identifier.

- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    if (property == kABPersonEmailProperty) {
        ABMultiValueRef emails = ABRecordCopyValue(person, property);
        CFIndex ix = ABMultiValueGetIndexForIdentifier(emails, identifier);
        CFStringRef email = ABMultiValueCopyValueAtIndex(emails, ix);

        [self dismissViewControllerAnimated:YES completion:nil];

        [self callMethodWithEmailString:(__bridge NSString *)(email)];
        if (email) CFRelease(email);
        if (emails) CFRelease(emails);
    }

    return NO;
}

Related Questions:

Community
  • 1
  • 1
davegaeddert
  • 3,139
  • 1
  • 21
  • 20