How to get a CNContact phone number(s) as string in Swift?

百般思念 提交于 2019-11-27 05:32:49

问题


I am attempting to retrieve the names and phone number(s) of all contacts and put them into arrays with Swift in iOS. I have made it this far:

func findContacts() -> [CNContact] {

    marrContactsNumber.removeAllObjects()
    marrContactsName.removeAllObjects()

    let store = CNContactStore()

    let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]

    let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)

    var contacts = [CNContact]()

    do {
        try store.enumerateContactsWithFetchRequest(fetchRequest, usingBlock: { (let contact, let stop) -> Void in
            contacts.append(contact)

            self.marrContactsName.addObject(contact.givenName + " " + contact.familyName)

            self.marrContactsNumber.addObject(contact.phoneNumbers)

            print(contact.phoneNumbers)
    }
    catch let error as NSError {
        print(error.localizedDescription)
    }

    print(marrContactsName.count)
    print(marrContactsNumber.count)

    return contacts
}

Once completed, marrContactsName contains an array of all my contacts' names exactly as expected. i.e. "John Doe". However, marrContactsNumber returns an array of values like

[<CNLabeledValue: 0x158a19950: identifier=F831DC7E-5896-420F-AE46-489F6C14DA6E,
label=_$!<Work>!$_, value=<CNPhoneNumber: 0x158a19640: countryCode=us, digits=6751420000>>,
<CNLabeledValue: 0x158a19a80: identifier=ECD66568-C6DD-441D-9448-BDEDDE9A68E1,
label=_$!<Work>!$_, value=<CNPhoneNumber: 0x158a199b0: countryCode=us, digits=5342766455>>]

I would like to know how to retrieve JUST the phone number(s) as a string value(s) i.e. "XXXXXXXXXX". Basically, how to call for the digit(s) value. Thanks!


回答1:


I found the solution: (contact.phoneNumbers[0].value as! CNPhoneNumber).valueForKey("digits") as! String




回答2:


you can get contact.phoneNumbers from CNLabeledValue:

for phoneNumber in contact.phoneNumbers {
  if let number = phoneNumber.value as? CNPhoneNumber,
      let label = phoneNumber.label {
      let localizedLabel = CNLabeledValue.localizedStringForLabel(label)
      print("\(localizedLabel)  \(number.stringValue)")
  }
}



回答3:


/* Get only first mobile number */

    let MobNumVar = (contact.phoneNumbers[0].value as! CNPhoneNumber).valueForKey("digits") as! String
    print(MobNumVar)

/* Get all mobile number */

    for ContctNumVar: CNLabeledValue in contact.phoneNumbers
    {
        let MobNumVar  = (ContctNumVar.value as! CNPhoneNumber).valueForKey("digits") as? String
        print(MobNumVar!)
    }

 /* Get mobile number with mobile country code */

    for ContctNumVar: CNLabeledValue in contact.phoneNumbers
    {
        let FulMobNumVar  = ContctNumVar.value as! CNPhoneNumber
        let MccNamVar = FulMobNumVar.valueForKey("countryCode") as? String
        let MobNumVar = FulMobNumVar.valueForKey("digits") as? String

        print(MccNamVar!)
        print(MobNumVar!)
    }



回答4:


Here is how you do it in swift 4

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

    if let phoneNo = contactProperty.value as? CNPhoneNumber{
        txtPhone.text = phoneNo.stringValue
    }else{
        txtPhone.text=""
    }
}



回答5:


Here's a solution I used with Swift 4.

func addPhoneNumber(_ contact: CNContact) {

    var numbers: [String] = []

    let validTypes = [
        CNLabelPhoneNumberiPhone,
        CNLabelPhoneNumberMobile,
        CNLabelPhoneNumberMain
    ]

    let validNumbers = contact.phoneNumbers.compactMap { phoneNumber -> String? in
        if let label = phoneNumber.label, validTypes.contains(label) {
            return phoneNumber.value.stringValue
        }
        return nil
    }

    guard numbers.count > 0 else {
        return
    }

    // process/use your numbers for this contact here
    DispatchQueue.main.async {
        self.sendSMSText(numbers)
    }
}

You can find available values for the validTypes array in the CNPhoneNumber header file.

They are:

CNLabelPhoneNumberiPhone
CNLabelPhoneNumberMobile
CNLabelPhoneNumberMain
CNLabelPhoneNumberHomeFax
CNLabelPhoneNumberWorkFax
CNLabelPhoneNumberOtherFax
CNLabelPhoneNumberPager



回答6:


The definition of a CNLabeledValue:

The CNLabeledValue class is a thread-safe class that defines an immutable value object that combines a contact property value with a label. For example, a contact phone number could have a label of Home, Work, iPhone, etc.

CNContact.phoneNumbers is an array of CNLabeledValues and each CNLabeledValue has a label and a value.

To print the phoneNumbers corresponding to a CNContact you can try:

for phoneNumber in contact.phoneNumbers {
    print("The \(phoneNumber.label) number of \(contact.givenName) is: \(phoneNumber.value)")
}



回答7:


In swift 3 you can get direclty

 if item.isKeyAvailable(CNContactPhoneNumbersKey){
        let phoneNOs=item.phoneNumbers
        let phNo:String
        for item in phoneNOs{
            print("Phone Nos \(item.value.stringValue)")
        }



回答8:


Keeping things simple:

let phoneNumbers: [String] = contact.phoneNumbers.compactMap { (phoneNumber: CNLabeledValue) in
    guard let number = phoneNumber.value.value(forKey: "digits") as? String else { return nil }
    return number
}



回答9:


Swift 3 "_$!<Mobile>!$_" This item is written to create difference as well as putting a piece of opportunity to rely on various options.

for con in contacts
{
    for num in con.phoneNumbers
    {
        if num.label == "_$!<Mobile>!$_"    //Please Don't Change this!
        {
            self.contactNames.append(con.givenName)
            self.contactNums.append(num.value.stringValue)
            break
        }
        else
        {
            continue
        }
    }
}

Here we have num.value.stringValue



来源:https://stackoverflow.com/questions/36343312/how-to-get-a-cncontact-phone-numbers-as-string-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!