简体   繁体   English

如何在Swift中以字符串形式获取CNContact电话号码?

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

I am attempting to retrieve the names and phone number(s) of all contacts and put them into arrays with Swift in iOS.我正在尝试检索所有联系人的姓名和电话号码,并在 iOS 中使用 Swift 将它们放入数组中。 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.完成后, marrContactsName完全按照预期包含我所有联系人姓名的数组。 ie "John Doe".即“约翰·多伊”。 However, marrContactsNumber returns an array of values like但是, marrContactsNumber返回一个值数组,如

[<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) ie "XXXXXXXXXX".我想知道如何仅检索电话号码作为字符串值,即“XXXXXXXXXX”。 Basically, how to call for the digit(s) value.基本上,如何调用数字值。 Thanks!谢谢!

I found the solution: (contact.phoneNumbers[0].value as! CNPhoneNumber).valueForKey("digits") as! String我找到了解决方案: (contact.phoneNumbers[0].value as! CNPhoneNumber).valueForKey("digits") as! String (contact.phoneNumbers[0].value as! CNPhoneNumber).valueForKey("digits") as! String

you can get contact.phoneNumbers from CNLabeledValue :您可以从CNLabeledValue获取contact.phoneNumbers

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)")
  }
}
/* 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!)
    }

Here is how you do it in swift 4这是你如何在 swift 4 中做到的

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

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

Here's a Swift 5 solution.这是一个 Swift 5 解决方案。

import Contacts

func sendMessageTo(_ contact: CNContact) {

    let validTypes = [
        CNLabelPhoneNumberiPhone,
        CNLabelPhoneNumberMobile,
        CNLabelPhoneNumberMain
    ]

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

    guard !numbers.isEmpty 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.您可以在 CNPhoneNumber 头文件中找到validTypes数组的可用值。

They are:他们是:

CNLabelPhoneNumberiPhone
CNLabelPhoneNumberMobile
CNLabelPhoneNumberMain
CNLabelPhoneNumberHomeFax
CNLabelPhoneNumberWorkFax
CNLabelPhoneNumberOtherFax
CNLabelPhoneNumberPager

The definition of a CNLabeledValue : CNLabeledValue的定义:

The CNLabeledValue class is a thread-safe class that defines an immutable value object that combines a contact property value with a label. CNLabeledValue 类是一个线程安全类,它定义了一个不可变值对象,该对象将联系人属性值与标签相结合。 For example, a contact phone number could have a label of Home, Work, iPhone, etc.例如,联系电话号码可能带有“家庭”、“工作”、“iPhone”等标签。

CNContact.phoneNumbers is an array of CNLabeledValues and each CNLabeledValue has a label and a value. CNContact.phoneNumbers 是一个 CNLabeledValues 数组,每个 CNLabeledValue 都有一个标签和一个值。

To print the phoneNumbers corresponding to a CNContact you can try:要打印与 CNContact 对应的电话号码,您可以尝试:

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

In swift 3 you can get direclty在 swift 3 你可以得到直接

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

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
}

for Swift 5+ Swift 5+

func removeSpecialCharactersFromContactNumberOfUser(_ contactNo : String) -> String? {

    let digits = CharacterSet(charactersIn: "0123456789").inverted
    let modifiedContactNo = contactNo.components(separatedBy: digits).joined(separator: "")

    if modifiedContactNo.count > 9 {

        return modifiedContactNo

    } else {

        return nil
    }
}

var number = phone.value.stringValue
number = number.starts(with: "+91") ? number.replacingOccurrences(of: "+91", with: "") : number

if let formattedNumber = removeSpecialCharactersFromContactNumberOfUser(number)  {
    //use this formattedNumber                 
}

This is to remove +91 from your phone number and it's working fine.这是从您的电话号码中删除 +91 并且它工作正常。

Swift 3 "_$!<Mobile>!$_" This item is written to create difference as well as putting a piece of opportunity to rely on various options. Swift 3 "_$!<Mobile>!$_"编写此项目是为了创造差异并提供依赖各种选项的机会。

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这里我们有num.value.stringValue

fetch without country code from phone contacts and also removed unwanted text such as dash, spaces etc.. and also post from phonetextfield import ContactsUI var phoneString:String!从电话联系人中获取不带国家/地区代码的内容,还删除了不需要的文本,例如破折号、空格等。还可以从 phonetextfield import ContactsUI var phoneString:String 发布!

func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
        let numbers = contact.phoneNumbers.first
        let a = (numbers?.value)?.stringValue ?? ""
        let myString = a
        let formattedString = myString.replacingOccurrences(of: " ", with: "")
        let newFormattedString = formattedString.replacingOccurrences(of: "(", with: "")
        let formatstring = newFormattedString.replacingOccurrences(of: ")", with: "")
        let  last10  = formatstring.replacingOccurrences(of: "-", with: "")
        phoneString = String(last10.suffix(10))
        phonetextField.text = phoneString
        
    }
    
    func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
        self.dismiss(animated: true, completion: nil)
    }
   @IBAction func inviteButton(_ sender : Any)
    {
        if phoneString == nil{
            phoneString =  phonetextField.text! //fetching from phonetextfield
            Phone = phoneString
        }
        else  {
            Phone = phoneString //fetching from phone contacts
        
        }
      }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM