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 controller, but I'm trying use my code and this not show never when I click in a contact. This only open the contact into native app ABPeoplePickerNavigationController.
var people = ABPeoplePickerNavigationController()
var addressBook: ABAddressBookRef?
func extractABAddressBookRef(abRef: Unmanaged<ABAddressBookRef>!) -> ABAddressBookRef? {
    if let ab = abRef {
        self.view.addSubview(people.view)
        return Unmanaged<NSObject>.fromOpaque(ab.toOpaque()).takeUnretainedValue()
    }
    return nil
}
I tried this function
func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!,didSelectPerson person: ABRecordRef!) {
    var unmanagedEmails = ABRecordCopyValue(people, kABPersonEmailProperty)
    let emailObj: ABMultiValueRef = Unmanaged.fromOpaque(unmanagedEmails.toOpaque()).takeUnretainedValue() as NSObject as ABMultiValueRef
    var index = 0 as CFIndex
    var unmanagedEmail = ABMultiValueCopyValueAtIndex(emailObj, index)
    var emailAddress:String = Unmanaged.fromOpaque(unmanagedEmail.toOpaque()).takeUnretainedValue() as NSObject as String
    println(emailAddress)      
}
Thanks!
Here is the latest framework for iOS 9 - ContactsUI
import ContactsUI
Conform to the CNContactPickerDelegate (No required methods)
Create a contacts picker object and present it:
let peoplePicker = CNContactPickerViewController()
peoplePicker.delegate = self
self.presentViewController(peoplePicker, animated: true, completion: nil)
Dismiss the CNContactPickerViewController in the contactPickerDidCancel delegate function
func contactPickerDidCancel(picker: CNContactPickerViewController) {
    picker.dismissViewControllerAnimated(true, completion: nil)
}
Here is how I Accessed a contacts name, phone numbers, phone number labels, and photo using the didSelectContact delegate function:
func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
//Dismiss the picker VC
picker.dismissViewControllerAnimated(true, completion: nil)
//See if the contact has multiple phone numbers
if contact.phoneNumbers.count > 1 {
    //If so we need the user to select which phone number we want them to use
    let multiplePhoneNumbersAlert = UIAlertController(title: "Which one?", message: "This contact has multiple phone numbers, which one did you want use?", preferredStyle: UIAlertControllerStyle.Alert)
    //Loop through all the phone numbers that we got back
    for number in contact.phoneNumbers {
        //Each object in the phone numbers array has a value property that is a CNPhoneNumber object, Make sure we can get that
        if let actualNumber = number.value as? CNPhoneNumber {
            //Get the label for the phone number
            var phoneNumberLabel = number.label
            //Strip off all the extra crap that comes through in that label
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("_", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("$", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("!", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("<", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString(">", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            //Create a title for the action for the UIAlertVC that we display to the user to pick phone numbers
            let actionTitle = phoneNumberLabel + " - " + actualNumber.stringValue
            //Create the alert action
            let numberAction = UIAlertAction(title: actionTitle, style: UIAlertActionStyle.Default, handler: { (theAction) -> Void in
                //Create an empty string for the contacts name
                var nameToSave = ""
                //See if we can get A frist name
                if contact.givenName == "" {
                    //If Not check for a last name
                    if contact.familyName == "" {
                        //If no last name set name to Unknown Name
                        nameToSave = "Unknown Name"
                    }else{
                        nameToSave = contact.familyName
                    }
                }else{
                    nameToSave = contact.givenName
                }
                // See if we can get image data
                if let imageData = contact.imageData {
                    //If so create the image
                    let userImage = UIImage(data: imageData)
                }
                //Do what you need to do with your new contact information here!
                //Get the string value of the phone number like this:
                actualNumber.stringValue  
            })
            //Add the action to the AlertController
            multiplePhoneNumbersAlert.addAction(numberAction)
        }
    }
    //Add a cancel action
    let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (theAction) -> Void in
        //Cancel action completion
    })
    //Add the cancel action
    multiplePhoneNumbersAlert.addAction(cancelAction)
    //Present the ALert controller
    self.presentViewController(multiplePhoneNumbersAlert, animated: true, completion: nil)
}else{
    //Make sure we have at least one phone number
    if contact.phoneNumbers.count > 0 {
        //If so get the CNPhoneNumber object from the first item in the array of phone numbers
        if let actualNumber = contact.phoneNumbers.first?.value as? CNPhoneNumber {
            //Get the label of the phone number
            var phoneNumberLabel = contact.phoneNumbers.first!.label
            //Strip out the stuff you don't need
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("_", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("$", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("!", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString("<", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            phoneNumberLabel = phoneNumberLabel.stringByReplacingOccurrencesOfString(">", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
            //Create an empty string for the contacts name
            var nameToSave = ""
            //See if we can get A frist name
            if contact.givenName == "" {
                //If Not check for a last name
                if contact.familyName == "" {
                    //If no last name set name to Unknown Name
                    nameToSave = "Unknown Name"
                }else{
                    nameToSave = contact.familyName
                }
            }else{
                nameToSave = contact.givenName
            }
            // See if we can get image data
            if let imageData = contact.imageData {
                //If so create the image
                let userImage = UIImage(data: imageData)
            }
            //Do what you need to do with your new contact information here!
            //Get the string value of the phone number like this:
            actualNumber.stringValue
        }
    }else{
        //If there are no phone numbers associated with the contact I call a custom funciton I wrote that lets me display an alert Controller to the user
        self.displayAlert("Missing info", message: "You have no phone numbers associated with this contact")
    }
}
}
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.
SWIFT3 IOS10 Working version of Jon Vogel for Swift 3 and IOS 10 and support to multiple contacts selection.
//
//  Created by JEFFERSON A NEITZKE on 30/01/17.
//  Copyright © 2017 JEFFERSON A NEITZKE. All rights reserved.
//
import UIKit
import ContactsUI
class Principal: UIViewController, CNContactPickerDelegate {
    var numeroADiscar: String = ""
    var userImage: UIImage? = nil
    var nameToSave = ""
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let peoplePicker = CNContactPickerViewController()
        peoplePicker.delegate = self
        self.present(peoplePicker, animated: true, completion: nil)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
        picker.dismiss(animated: true, completion: nil)
    }
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
        // I only want single selection
        if contacts.count != 1 {
            return
        } else {
            //Dismiss the picker VC
            picker.dismiss(animated: true, completion: nil)
            let contact: CNContact = contacts[0]
            //See if the contact has multiple phone numbers
            if contact.phoneNumbers.count > 1 {
                //If so we need the user to select which phone number we want them to use
                let multiplePhoneNumbersAlert = UIAlertController(title: "Which one?", message: "This contact has multiple phone numbers, which one did you want use?", preferredStyle: UIAlertControllerStyle.alert)
                //Loop through all the phone numbers that we got back
                for number in contact.phoneNumbers {
                    //Each object in the phone numbers array has a value property that is a CNPhoneNumber object, Make sure we can get that
                    let actualNumber = number.value as CNPhoneNumber
                    //Get the label for the phone number
                    var phoneNumberLabel = number.label
                    //Strip off all the extra crap that comes through in that label
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "_", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "$", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "!", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "<", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: ">", with: "")
                    //Create a title for the action for the UIAlertVC that we display to the user to pick phone numbers
                    let actionTitle = phoneNumberLabel! + " - " + actualNumber.stringValue
                    //Create the alert action
                    let numberAction = UIAlertAction(title: actionTitle, style: UIAlertActionStyle.default, handler: { (theAction) -> Void in
                        //See if we can get A frist name
                        if contact.givenName == "" {
                            //If Not check for a last name
                            if contact.familyName == "" {
                                //If no last name set name to Unknown Name
                                self.nameToSave = "Unknown Name"
                            }else{
                                self.nameToSave = contact.familyName
                            }
                        } else {
                            self.nameToSave = contact.givenName
                        }
                        // See if we can get image data
                        if let imageData = contact.imageData {
                            //If so create the image
                            self.userImage = UIImage(data: imageData)!
                        }
                        //Do what you need to do with your new contact information here!
                        //Get the string value of the phone number like this:
                        self.numeroADiscar = actualNumber.stringValue
                    })
                    //Add the action to the AlertController
                    multiplePhoneNumbersAlert.addAction(numberAction)
                }
                //Add a cancel action
                let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (theAction) -> Void in
                    //Cancel action completion
                })
                //Add the cancel action
                multiplePhoneNumbersAlert.addAction(cancelAction)
                //Present the ALert controller
                self.present(multiplePhoneNumbersAlert, animated: true, completion: nil)
            } else {
                //Make sure we have at least one phone number
                if contact.phoneNumbers.count > 0 {
                    //If so get the CNPhoneNumber object from the first item in the array of phone numbers
                    let actualNumber = (contact.phoneNumbers.first?.value)! as CNPhoneNumber
                    //Get the label of the phone number
                    var phoneNumberLabel = contact.phoneNumbers.first!.label
                    //Strip out the stuff you don't need
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "_", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "$", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "!", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: "<", with: "")
                    phoneNumberLabel = phoneNumberLabel?.replacingOccurrences(of: ">", with: "")
                    //Create an empty string for the contacts name
                    self.nameToSave = ""
                    //See if we can get A frist name
                    if contact.givenName == "" {
                        //If Not check for a last name
                        if contact.familyName == "" {
                            //If no last name set name to Unknown Name
                            self.nameToSave = "Unknown Name"
                        }else{
                            self.nameToSave = contact.familyName
                        }
                    } else {
                        nameToSave = contact.givenName
                    }
                    // See if we can get image data
                    if let imageData = contact.imageData {
                        //If so create the image
                        self.userImage = UIImage(data: imageData)
                    }
                    //Do what you need to do with your new contact information here!
                    //Get the string value of the phone number like this:
                    self.numeroADiscar = actualNumber.stringValue
                } else {
                    //If there are no phone numbers associated with the contact I call a custom funciton I wrote that lets me display an alert Controller to the user
                    let alert = UIAlertController(title: "Missing info", message: "You have no phone numbers associated with this contact", preferredStyle: UIAlertControllerStyle.alert)
                    let cancelAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
                    alert.addAction(cancelAction)
                    present(alert, animated: true, completion: nil)
                }
            }
        }
    }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With