问题
In my code I use ABPeoplePickerNavigationController to select person. After user select person from contact list, I look if specified person record have any phone number:
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
ABMutableMultiValueRef phones;
phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
if (phones == nil || ABMultiValueGetCount(phones) == 0)
{
return NO;
}
// other code....
}
I created contact, added phone number to it and tested my code. In iOS 5 this code works well. phones variable contains one phone number.
But in iOS 6, after linking contact to facebook account, phones variable doesn't contain any values.
After unlinking contact with facebook account everything works well again.
How can I read person phone numbers this method?
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
UPD
If i return YES in the function above, then in function
(BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
I can read all person phone numbers in normal way. So why I can't read them in the first function?
回答1:
I found the answer to my question. If the contact is linked, then in method
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
you recieve a reference to person, which respesents a linked contact. To retrieve all phone numbers you need to get all linked contacts and then look for phone numbers in that contacts. I do this with the following code:
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
ABMutableMultiValueRef phones;
phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
if (phones == nil || ABMultiValueGetCount(phones) == 0)
{
CFArrayRef linkedContacts = ABPersonCopyArrayOfAllLinkedPeople(person);
phones = ABMultiValueCreateMutable(kABPersonPhoneProperty);
ABMultiValueRef linkedPhones;
for (int i = 0; i < CFArrayGetCount(linkedContacts); i++)
{
ABRecordRef linkedContact = CFArrayGetValueAtIndex(linkedContacts, i);
linkedPhones = ABRecordCopyValue(linkedContact, kABPersonPhoneProperty);
if (linkedPhones != nil && ABMultiValueGetCount(linkedPhones) > 0)
{
for (int j = 0; j < ABMultiValueGetCount(linkedPhones); j++)
{
ABMultiValueAddValueAndLabel(phones, ABMultiValueCopyValueAtIndex(linkedPhones, j), NULL, NULL);
}
}
CFRelease(linkedPhones);
}
CFRelease(linkedContacts);
if (ABMultiValueGetCount(phones) == 0)
{
CFRelease(phones);
return NO;
}
}
// other code ...
}
With that code i received all phone numbers for linked contact.
回答2:
In the solution re: linked contacts you need to change the line which stores the phone numbers found to
ABMultiValueAddValueAndLabel(phones, ABMultiValueCopyValueAtIndex(linkedPhones, j),
ABMultiValueCopyLabelAtIndex(linkedPhones, j), NULL);
so that you can use the 'phones' to check by label later. The solution given just stores the numbers so you would not be able to test against constants like kABPersonPhoneMainLabel
This approach is also used for emails and addresses. For addresses you pull out the parts like this:-
CFDictionaryRef dict = ABMultiValueCopyValueAtIndex(address, 0);
street.text = CFBridgingRelease(CFDictionaryGetValue(dict, kABPersonAddressStreetKey));
来源:https://stackoverflow.com/questions/13032565/ios-6-address-book-empty-kabpersonphoneproperty