如何在Swift中选择与ABPeoplePickerNavigationController的联系人? [英] How to select a contact with ABPeoplePickerNavigationController in Swift?

查看:96
本文介绍了如何在Swift中选择与ABPeoplePickerNavigationController的联系人?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将 ABPeoplePickerNavigationController 添加到我的第一个视图控制器中。我希望当我选择一个联系人时显示要在其他视图控制器中显示的信息,但是我正在尝试使用自己的代码,并且当我单击某个联系人时,该信息永远不会显示。这只会将联系人打开到本机应用程序 ABPeoplePickerNavigationController

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
}

我尝试了此功能

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)      
}

谢谢!

推荐答案

一些想法:


  1. 您设置好了吗 people 选择器控制器的 peoplePickerDelegate 属性?如果您不这样做,就不会尝试在您的课程中调用这些方法。因此:

  1. 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)


  • 您的示例方法是在您引用 people 时调用 ABRecordCopyValue 。那是您的选择器控制器。我假设您要引用 person ,即作为参数传递的 ABRecordRef!

  • 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.

    在尝试访问它之前,您可能还想确保自己确实有一个电子邮件地址。您可以使用 ABMultiValueGetCount

    You might also want to make sure you actually have an email address before trying to access it. You can use ABMultiValueGetCount.

    我还认为您也可以从Opaque中消除 / 去不透明跳舞。

    I also think you can also eliminate that fromOpaque/toOpaque dance.

    结果如下:

    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,请使用:

  • 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)")
    }
    

    要支持iOS 7,0,您还需要添加:

    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
    }
    


  • 顺便说一句,iOS 8提供了一项功能来控制是否联系人是否启用。由于您支持iOS 7和8,因此您希望有条件地使用它,例如:

  • 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.

    很明显,如果使用iOS 9及更高版本,则应将所有这些信息退役并使用 ContactsUI 框架,从而进一步简化了代码。

    Obviously, if using iOS 9 and later, you should retire all of this and use the ContactsUI framework, which simplifies the code further.

    这篇关于如何在Swift中选择与ABPeoplePickerNavigationController的联系人?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆