Search code examples
iosswiftcncontactpicker

How to get the selected contactProperty from CNContactPickerViewController


I'm currently able to get a contact from the contacts app, but the problem I'm facing that I need to be able to select the contact I want to import to my app , if the contact have more than 1 phone number, I always get the first number, here is the code I'm using:

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

The problem with line:

contactProperty.contact.phoneNumbers.first

There are two options only for contactProperty.contact.phoneNumbers .first or .last

If there is something like .selected, it would solve the problem.


Solution

  • There is something called Main telephone number that you could use

    var phoneNumber: String?
    
    if let mainNumber = numbers.first(where: { $0.label == CNLabelPhoneNumberMain }) {
        phoneNumber = mainNumber.value.stringValue
    } else {
        phoneNumber = numbers.first?.value.stringValue //or some other default value
    }
    

    Note that I changed the definition of numbers to be the array of phone numbers

    let numbers = contactProperty.contact.phoneNumbers
    

    Full code:

    func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
    
        let numbers = contactProperty.contact.phoneNumbers    
        var phoneNumber: String?
    
        if let mainNumber = numbers.first(where: { $0.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()
        }
    }