1
votes

Comment obtenir le contactProperty sélectionné à partir de CNContactPickerViewController

Je suis actuellement en mesure d'obtenir un contact à partir de l'application Contacts, mais le problème auquel je suis confronté est que je dois pouvoir sélectionner le contact que je souhaite importer dans mon application, si le contact possède plus d'un téléphone numéro, j'obtiens toujours le premier numéro, voici le code que j'utilise:

contactProperty.contact.phoneNumbers.first

Le problème avec la ligne:

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

Là sont deux options uniquement pour contactProperty.contact.phoneNumbers .first ou .last

S'il y a quelque chose comme .selected , cela résoudrait le problème.


4 commentaires

Appuyez-vous sur le nom du contact ou sur l'un des numéros de téléphone du contact (est-ce possible?)?


phoneNumbers est un tableau. Vous obtenez un seul nombre parce que vous choisissez le premier objet du tableau. Utilisez plutôt le tableau dans son ensemble.


@PGDev, elle ne veut qu'un seul numéro de la liste qui est enregistré comme numéro principal.


En utilisant (_ picker: CNContactPickerViewController, didSelect contact: CNContact) activé pour sélectionner le contact uniquement. L'utilisation de (_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) m'a permis d'ouvrir le contact et d'afficher les numéros de téléphone qu'il contient et d'en sélectionner un, mais quel que soit ce que je sélectionne, j'obtiens toujours le premier numéro.


3 Réponses :


0
votes

Il y a quelque chose appelé Numéro de téléphone principal que vous pouvez utiliser

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

Notez que j'ai changé la définition des nombres pour être le tableau des numéros de téléphone p >

let numbers = contactProperty.contact.phoneNumbers

Code complet:

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
}


6 commentaires

Ce genre de réponse est tellement ennuyeux, comment puis-je améliorer ma réponse avec une réponse comme "ça n'a pas fonctionné"?


Il contient des erreurs de compilation, tout doit être déballé. même avec ça, ça n'a pas fonctionné. Peut-être pouvez-vous montrer comment implémenter votre code dans un exemple?


Merci Joakim, le code fonctionne, je devais juste remplacer numbers.first par numbers.last dans votre exemple: else {phoneNumber = numbers.last? .Value.stringValue // ou une autre valeur par défaut}


Si je lis ceci correctement, cette solution ne fonctionne que dans les scénarios où les étiquettes de numéro de téléphone correspondent aux hypothèses.


@benc Quelles hypothèses voulez-vous dire? Il utilise le numéro de téléphone sélectionné comme numéro de téléphone principal, pas de libellés.


oh, je vois que vous préférez un numéro intitulé "principal" ...



0
votes

Je suis d'accord avec la solution de Joakim Danielson.

Mais il existe une autre solution pour obtenir un numéro de téléphone spécifique qui est stocké dans un numéro de mobile comme domicile, mobile, fax, etc.

Tout obtenir numéros de contact et énumérer sur chaque numéro et vérifier les valeurs étiquetées. Voir le code suivant.

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


0 commentaires

0
votes

contactProperty.contacts est une référence arrière au CNContact dans lequel se trouve la propriété sélectionnée ...

Chaque propriété est représentée par une instance de CNContactProperty, qui fournit un tuple pouvant contenir trois ou cinq valeurs, selon que la propriété est membre d'un tableau de valeurs étiquetées. CNContactProperty

Vous devez donc utiliser directement les informations var de la propriété:

Par exemple, la propriété phoneNumbers est membre d'un tableau de valeurs étiquetées, de sorte que le tuple CNContactProperty contient le contact, la clé, la valeur, l'identifiant et le libellé.

CNContactProperty

REMARQUE: j'ai appris cela en lisant une autre réponse S-O, mais je n'arrive pas à la trouver pour le moment. Le cas échéant, dupliquez ou modifiez ainsi,


0 commentaires