如何从 CNContactPickerViewController 获取选中的 contactProperty

How to get the selected contactProperty from CNContactPickerViewController

我目前可以从联系人应用程序中获取联系人,但我面临的问题是我需要能够 select 我想导入我的应用程序的联系人,如果联系人有超过 1 个 phone 号码,我总是得到第一个号码,这是我使用的代码:

func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {

    let numbers     = contactProperty.contact.phoneNumbers.first
    let firstName   = contactProperty.contact.givenName
    let lastName    = contactProperty.contact.familyName
    let phoneNumber = (numbers?.value)?.stringValue ?? ""

    /// Duplicate phone numbers will not be saved
    if phoneNumbers.contains(phoneNumber) {
        return
    }
    /// Saving selected contact in Core Data
    CoreDataManager.sharedInstance.savePhoneNumberInCoreData(FirstName: firstName, LastName: lastName, PhoneNumber: phoneNumber)

    DispatchQueue.main.async { [weak self] in
        self?.tableView.reloadData()
    }
}

线路问题:

contactProperty.contact.phoneNumbers.first

只有contactProperty.contact.phoneNumbers.first.last

两个选项

如果有.selected之类的,就可以解决问题。

有一个叫做 Main telephone 的号码可以使用

var phoneNumber: String?

if let mainNumber = numbers.first(where: { [=10=].label == CNLabelPhoneNumberMain }) {
    phoneNumber = mainNumber.value.stringValue
} else {
    phoneNumber = numbers.first?.value.stringValue //or some other default value
}

请注意,我将 numbers 的定义更改为 phone 个数字的数组

let numbers = contactProperty.contact.phoneNumbers

完整代码:

func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {

    let numbers = contactProperty.contact.phoneNumbers    
    var phoneNumber: String?

    if let mainNumber = numbers.first(where: { [=12=].label == CNLabelPhoneNumberMain }) {
        phoneNumber = mainNumber.value.stringValue
    } else {
        phoneNumber = numbers.first?.value.stringValue //or some other default value
    }

    if phoneNumber == nil || phoneNumbers.contains(phoneNumber) {
        return
    }

    let firstName = contactProperty.contact.givenName
    let lastName = contactProperty.contact.familyName   

    CoreDataManager.sharedInstance.savePhoneNumberInCoreData(FirstName: firstName, LastName: lastName, PhoneNumber: phoneNumber)

    DispatchQueue.main.async { [weak self] in
        self?.tableView.reloadData()
    }
}

我同意 Joakim Danielson 的解决方案。

但还有另一种解决方案可以获取存储在手机号码中的特定 phone 号码,例如家庭、手机、传真等

获取联系人的所有号码并枚举每个号码并检查标记值。请参阅以下代码。

let numbers = contact.phoneNumbers

numbers.forEach { (c) in

    if let label = c.label {

        let localizedLabel = CNLabeledValue<NSCopying & NSSecureCoding>.localizedString(forLabel: label)
        print("\(localizedLabel)")

        switch localizedLabel.lowercased() {

        case "home":
            let homeNumber = c.value
            break

        case "mobile":
            let mobileNumber = c.value
            break

        default:
            break
        }
    }
}

contactProperty.contacts 是 back-reference 到 CNContact 所选 属性 住在...

Each property is represented by an instance of CNContactProperty, which provides a tuple that can contain three or five values, depending on whether the property is a member of an array of labeled values. CNContactProperty

因此,您应该直接使用 属性 的信息 var

For example, the phoneNumbers property is a member of an array of labeled values, so the CNContactProperty tuple contains the contact, key, value, identifier, and label.

CNContactProperty

注意:我是通过阅读另一个 S-O 答案了解到这一点的,但我现在似乎找不到它。如果合适的话,欺骗或编辑,