I have added the ABPeoplePickerNavigationController
into my first view controller. I want that when I select a contact show the info to show in other view controlle
A couple of thoughts:
Have you set the peoplePickerDelegate
property of the people
picker controller? If you don't do that, it won't know to try to call these methods in your class. Thus:
people.peoplePickerDelegate = self
presentViewController(people, animated: true, completion: nil)
Your example method is referencing people
when you call ABRecordCopyValue
. That's your picker controller. I assume you meant to reference person
, the ABRecordRef!
that was passed as a parameter.
You might also want to make sure you actually have an email address before trying to access it. You can use ABMultiValueGetCount
.
I also think you can also eliminate that fromOpaque
/toOpaque
dance.
This yields:
func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController, didSelectPerson person: ABRecord) {
let emails: ABMultiValueRef = ABRecordCopyValue(person, kABPersonEmailProperty).takeRetainedValue()
if ABMultiValueGetCount(emails) > 0 {
let index = 0 as CFIndex
let emailAddress = ABMultiValueCopyValueAtIndex(emails, index).takeRetainedValue() as! String
print(emailAddress)
} else {
print("No email address")
}
}
If you need to support iOS 7, too, use:
func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController, shouldContinueAfterSelectingPerson person: ABRecord, property: ABPropertyID, identifier: ABMultiValueIdentifier) -> Bool {
let multiValue: ABMultiValueRef = ABRecordCopyValue(person, property).takeRetainedValue()
let index = ABMultiValueGetIndexForIdentifier(multiValue, identifier)
let email = ABMultiValueCopyValueAtIndex(multiValue, index).takeRetainedValue() as! String
print("email = \(email)")
peoplePicker.dismissViewControllerAnimated(true, completion: nil)
return false
}
You might, though, rather than assuming the user only wanted the first email address, instead, let them click through and pick one of the possible multiple email addresses the contact had. So, first, you might want to eliminate some of the "noise", by telling the picker that you only want to see email addresses:
people.peoplePickerDelegate = self
people.displayedProperties = [NSNumber(int: kABPersonEmailProperty)]
presentViewController(people, animated: true, completion: nil)
And then, remove the prior method we've been discussing, and instead implement:
func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, didSelectPerson person: ABRecordRef!, property: ABPropertyID, identifier: ABMultiValueIdentifier) {
let multiValue: ABMultiValueRef = ABRecordCopyValue(person, property).takeRetainedValue()
let index = ABMultiValueGetIndexForIdentifier(multiValue, identifier)
let email = ABMultiValueCopyValueAtIndex(multiValue, index).takeRetainedValue() as String
println("email = \(email)")
}
And to support iOS 7,0, too, you'd add:
func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController, shouldContinueAfterSelectingPerson person: ABRecord, property: ABPropertyID, identifier: ABMultiValueIdentifier) -> Bool {
let multiValue: ABMultiValueRef = ABRecordCopyValue(person, property).takeRetainedValue()
let index = ABMultiValueGetIndexForIdentifier(multiValue, identifier)
let email = ABMultiValueCopyValueAtIndex(multiValue, index).takeRetainedValue() as! String
print("email = \(email)")
peoplePicker.dismissViewControllerAnimated(true, completion: nil)
return false
}
By the way, iOS 8 offers a feature to control whether a contact is enabled or not. Since you're supporting iOS 7 and 8, you'd want to employ that conditionally, such as:
if people.respondsToSelector(Selector("predicateForEnablingPerson")) {
people.predicateForEnablingPerson = NSPredicate(format: "emailAddresses.@count > 0")
}
This gives the user visual indication whether there is even an email address for the individual, and prevents them from selecting entry without email address.
Obviously, if using iOS 9 and later, you should retire all of this and use the ContactsUI
framework, which simplifies the code further.