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.
3 Réponses :
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
}
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" ...
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
}
}
}
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é.
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,
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.