我已将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)
}
谢谢!
几个想法:
>你设置peoplePickerDelegate属性的人选择器控制器?如果你不这样做,就不会在课堂上尝试这些方法.从而:
people.peoplePickerDelegate = self presentViewController(people,animated: true,completion: nil)
>当您调用ABRecordcopyValue时,您的示例方法引用了人.这是你的选择器控制器.我假设你的意思是引用人,ABRecordRef!作为参数传递.
您可能还想确保您在尝试访问电子邮件之前确实有一个电子邮件地址.您可以使用ABMultiValueGetCount.
我也认为你也可以从Opaque / 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,completion: nil)
然后,删除我们一直在讨论的先前的方法,而不是实现:
func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!,didSelectPerson person: ABRecordRef!,identifier: ABMultiValueIdentifier) {
let multiValue: ABMultiValueRef = ABRecordcopyValue(person,index).takeRetainedValue() as String
println("email = \(email)")
}
而且,为了支持iOS 7,您还可以添加:
func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController,completion: nil)
return false
}
>顺便说一下,iOS 8提供了一个功能来控制联系人是否启用.由于您支持iOS 7和8,您需要有条件地使用,例如:
if people.respondsToSelector(Selector("predicateForEnablingPerson")) {
people.predicateForEnablingPerson = nspredicate(format: "emailAddresses.@count > 0")
}
这给用户可视化指示是否还有个人的电子邮件地址,并阻止他们选择没有电子邮件地址的条目.
显然,如果使用iOS 9和更高版本,您应该退出所有这些,并使用ContactsUI框架,这进一步简化了代码.