问题
we're having an issue where incorrect selections are being returned from the contacts database on some devices. Is there a way to modify the below code to only return the selected item from a persons contact information? In this case we want the exact selected email address from a persons contact to be returned.
Thanks in advance for the help! Heres the code...
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property: (ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
NSMutableDictionary *contactInfoDict = [[NSMutableDictionary alloc]
initWithObjects:@[@"", @"", @""]
forKeys:@[@"first_name", @"last_name", @"email"]];
// Use a general Core Foundation object.
CFTypeRef generalCFObject = ABRecordCopyValue(person, kABPersonFirstNameProperty);
// Get the first name.
if (generalCFObject) {
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"first_name"];
CFRelease(generalCFObject);
}
// Get the last name.
generalCFObject = ABRecordCopyValue(person, kABPersonLastNameProperty);
if (generalCFObject) {
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"last_name"];
CFRelease(generalCFObject);
}
// Load selected email addre'
if (property == kABPersonEmailProperty) {
ABMultiValueRef emails = ABRecordCopyValue(person, property);
CFIndex ix = ABMultiValueGetIndexForIdentifier(emails, identifier);
CFStringRef email = ABMultiValueCopyValueAtIndex(emails, ix);
emailAccount = (__bridge NSString *)(email);
[contactInfoDict setObject:emailAccount forKey:@"email"];
if (email) CFRelease(email);
if (emails) CFRelease(emails);
}
// init array
if (_arrContactsData == nil) {
_arrContactsData = [[NSMutableArray alloc] init];
}
// Send contact to server
[self sendContact:contactInfoDict];
// Set data for contacts
[_arrContactsData addObject:contactInfoDict];
// Reload the table view data.
[self.myTable reloadData];
// Dismiss the address book view controller.
[_addressBookController dismissViewControllerAnimated:YES completion:nil];
return NO;
}
回答1:
Your code is correct.
Are the users experiencing the problem using iOS 8, by any chance? I discovered a bug in iOS 8 beta 6. If you:
Create a contact with email addresses:

Edit the contact, adding an email address and deleting one of the other email addresses:
(Note, don't just edit one of the email addresses, but rather add a new email address and remove and old one.)
In iOS 7, if you iterate through the email addresses, you will see:
{ identifier = 1; index = 0; label = "_$!<Work>!$_"; value = "work@gmail.com"; }, { identifier = 2; index = 1; label = "_$!<Other>!$_"; value = "other@gmail.com"; }This is correct. (When the contact was first created, the identifiers were
0and1, when I add the "other" email address, that gets an identifier of2; when I delete the "home" email address, the email address with the identifier of0is deleted, but the other identifiers are correctly unaltered.) Thus, if you tap on the "work" email address,shouldContinueAfterSelectingPersonwill return anABMultiValueIdentifierof1, which translates to aCFIndexof0, which will correctly return the "work" email address.In iOS 8 Beta 6, however, the
ABMultiValueRefis incorrectly represented as:{ identifier = 0; index = 0; label = "_$!<Work>!$_"; value = "work@gmail.com"; }, { identifier = 1; index = 1; label = "_$!<Other>!$_"; value = "other@gmail.com"; }These identifiers are incorrect. Worse, if you tap on the "work" email address,
didSelectPerson(which replaces the deprecatedshouldContinueAfterSelectingPerson) will return aABMultiValueIdentifierof1(which is what it should have been ... it looks like this delegate method returns the appropriateidentifier, but that theABRecordReffor this edited record has the wrong identifiers ... not sure how they did that!), which translates to aCFIndexof1, which will correctly return the "other" email address (!).Worse, if you tapped on the "other" email address,
didSelectPersonwill return aABMultiValueIdentifierof2(which is what it should have been), but if you try to retrieve theCFIndex, you'll get-1(because no suchABMultiValueIdentifierexists) and because the app doesn't check for this, any attempt to useABMultiValueCopyValueAtIndexwith this invalid index will result in crash!
This bug seems to be fixed in the iOS8 GM seed, so it appears to be a beta problem only.
来源:https://stackoverflow.com/questions/25756990/how-do-you-retrieve-only-the-select-property-from-your-ios-contacts
