use*_*888 17 addressbook peoplepicker abaddressbook addressbookui swift
我已将其添加ABPeoplePickerNavigationController到我的第一个视图控制器中.我希望当我选择一个联系人时显示要在其他视图控制器中显示的信息,但我正在尝试使用我的代码,这在我点击联系人时不会显示.这只会打开联系人到本机应用程序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
}
我试过这个功能
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)      
}
谢谢!
Rob*_*Rob 17
几点想法:
您是否设置peoplePickerDelegate了people选择器控制器的属性?如果你不这样做,它将不知道尝试在你的类中调用这些方法.从而:
people.peoplePickerDelegate = self
presentViewController(people, animated: true, completion: nil)
您people调用时的示例方法是引用ABRecordCopyValue.那是你的选择控制器.我假设您要参考person,ABRecordRef!那是作为参数传递的.
您可能还想确保在尝试访问之前确实拥有电子邮件地址.你可以用ABMultiValueGetCount.
我也认为你也可以消除fromOpaque/ toOpaque跳舞.
这会产生:
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")
    }
}
如果您还需要支持iOS 7,请使用:
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
}
但是,您可能不是假设用户只想要第一个电子邮件地址,而是让他们点击并选择联系人可能的多个电子邮件地址之一.因此,首先,您可能希望通过告诉选择器您只想查看电子邮件地址来消除一些"噪音":
people.peoplePickerDelegate = self
people.displayedProperties = [NSNumber(int: kABPersonEmailProperty)]
presentViewController(people, animated: true, completion: nil)
然后,删除我们一直在讨论的先前方法,而不是实现:
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)")
}
并且为了支持iOS 7,0,你还要添加:
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
}
顺便说一句,iOS 8提供了一个控制是否启用联系人的功能.由于您支持iOS 7和8,因此您需要有条件地使用它,例如:
if people.respondsToSelector(Selector("predicateForEnablingPerson")) {
    people.predicateForEnablingPerson = NSPredicate(format: "emailAddresses.@count > 0")
}
这为用户提供了视觉指示,即使是个人的电子邮件地址是否存在,并且阻止他们选择没有电子邮件地址的条目.
显然,如果使用iOS 9及更高版本,您应该退出所有这些并使用ContactsUI框架,这进一步简化了代码.
Jon*_*gel 17
这是iOS 9的最新框架 - ContactsUI
导入ContactsUI
符合CNContactPickerDelegate(没有必要的方法)
创建联系人选择器对象并显示它:
let peoplePicker = CNContactPickerViewController()
peoplePicker.delegate = self
self.presentViewController(peoplePicker, animated: true, completion: nil)
在contactPickerDidCancel委托函数中关闭CNContactPickerViewController
func contactPickerDidCancel(picker: CNContactPickerViewController) {
    picker.dismissViewControllerAnimated(true, completion: nil)
}
以下是我使用didSelectContact委托功能访问联系人姓名,电话号码,电话号码标签和照片的方法:
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")
    }
}
}
SWIFT3 IOS10适用于Swift 3和IOS 10 的Jon Vogel工作版,支持多种联系人选择.
//
//  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)
                }
            }
        }
    }
}
| 归档时间: | 
 | 
| 查看次数: | 15136 次 | 
| 最近记录: |