Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正在获取ios Swift中的所有联系人?_Ios_Swift_Cncontact - Fatal编程技术网

正在获取ios Swift中的所有联系人?

正在获取ios Swift中的所有联系人?,ios,swift,cncontact,Ios,Swift,Cncontact,我知道ios swift有一个可以获取联系人的方法,但我找不到任何方法将所有联系人一起获取,这样我就可以访问该阵列中的每个联系人。所有获取联系人的方法似乎都需要某种条件。有什么方法可以让我把所有的联系人联系在一起吗 谢谢对联系人框架问题的许多回答建议迭代各种容器(帐户)。然而,苹果的文档将“统一联系人”描述为 代表同一个人的不同帐户中的联系人可能会自动链接在一起。链接联系人在OS X和iOS应用程序中显示为统一联系人。统一联系人是合并到一个联系人中的一组链接联系人的内存中临时视图 默认情况下,“

我知道ios swift有一个可以获取联系人的方法,但我找不到任何方法将所有联系人一起获取,这样我就可以访问该阵列中的每个联系人。所有获取联系人的方法似乎都需要某种条件。有什么方法可以让我把所有的联系人联系在一起吗


谢谢

对联系人框架问题的许多回答建议迭代各种容器(帐户)。然而,苹果的文档将“统一联系人”描述为

代表同一个人的不同帐户中的联系人可能会自动链接在一起。链接联系人在OS X和iOS应用程序中显示为统一联系人。统一联系人是合并到一个联系人中的一组链接联系人的内存中临时视图

默认情况下,“联系人”框架返回统一的联系人。每个获取的统一联系人(CNContact)对象都有自己的唯一标识符,该标识符不同于链接联系人集中任何单个联系人的标识符。统一联系人的重新蚀刻应使用其标识符完成。

因此,在单个数组中获取(部分,基于键)联系人列表的最简单方法如下:

      var contacts = [CNContact]()
    let keys = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName)]
    let request = CNContactFetchRequest(keysToFetch: keys)
    
    let contactStore = CNContactStore()
    do {
        try contactStore.enumerateContacts(with: request) {
            (contact, stop) in
            // Array containing all unified contacts from everywhere
            contacts.append(contact)
        }
    }
    catch {
        print("unable to fetch contacts")
    }

Swift 4和5。我已经创建了类PhoneContacts。请将NSContactsUsageDescription密钥添加到info.plist文件中

 import Foundation
 import ContactsUI

class PhoneContacts {

    class func getContacts(filter: ContactsFilter = .none) -> [CNContact] { //  ContactsFilter is Enum find it below

        let contactStore = CNContactStore()
        let keysToFetch = [
            CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
            CNContactPhoneNumbersKey,
            CNContactEmailAddressesKey,
            CNContactThumbnailImageDataKey] as [Any]

        var allContainers: [CNContainer] = []
        do {
            allContainers = try contactStore.containers(matching: nil)
        } catch {
            print("Error fetching containers")
        }

        var results: [CNContact] = []

        for container in allContainers {
            let fetchPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)

            do {
                let containerResults = try contactStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keysToFetch as! [CNKeyDescriptor])
                results.append(contentsOf: containerResults)
            } catch {
                print("Error fetching containers")
            }
        }
        return results
    }
}
在另一个类中调用上述方法

import ContactsUI
func phoneNumberWithContryCode() -> [String] {

    let contacts = PhoneContacts.getContacts() // here calling the getContacts methods
    var arrPhoneNumbers = [String]()
    for contact in contacts {
        for ContctNumVar: CNLabeledValue in contact.phoneNumbers {
            if let fulMobNumVar  = ContctNumVar.value as? CNPhoneNumber {
                //let countryCode = fulMobNumVar.value(forKey: "countryCode") get country code
                   if let MccNamVar = fulMobNumVar.value(forKey: "digits") as? String {
                        arrPhoneNumbers.append(MccNamVar)
                }
            }
        }
    }
    return arrPhoneNumbers // here array has all contact numbers.
}
现在,获取联系人的电子邮件和电话

    enum ContactsFilter {
        case none
        case mail
        case message
    }

    var phoneContacts = [PhoneContact]() // array of PhoneContact(It is model find it below) 
    var filter: ContactsFilter = .none

    self.loadContacts(filter: filter) // Calling loadContacts methods

       fileprivate func loadContacts(filter: ContactsFilter) {
            phoneContacts.removeAll()
            var allContacts = [PhoneContact]()
            for contact in PhoneContacts.getContacts(filter: filter) {
                allContacts.append(PhoneContact(contact: contact))
            }

            var filterdArray = [PhoneContact]()
            if self.filter == .mail {
                filterdArray = allContacts.filter({ $0.email.count > 0 }) // getting all email 
            } else if self.filter == .message {
                filterdArray = allContacts.filter({ $0.phoneNumber.count > 0 })
            } else {
                filterdArray = allContacts
            }
            phoneContacts.append(contentsOf: filterdArray)

  for contact in phoneContacts {
      print("Name -> \(contact.name)")
      print("Email -> \(contact.email)")
      print("Phone Number -> \(contact.phoneNumber)")
    }
    let arrayCode  = self.phoneNumberWithContryCode()
    for codes in arrayCode {
      print(codes)
    }
     DispatchQueue.main.async {
       self.tableView.reloadData() // update your tableView having phoneContacts array
              }
            }
        }
电话联系模型类

import Foundation
import ContactsUI

class PhoneContact: NSObject {

    var name: String?
    var avatarData: Data?
    var phoneNumber: [String] = [String]()
    var email: [String] = [String]()
    var isSelected: Bool = false
    var isInvited = false

    init(contact: CNContact) {
        name        = contact.givenName + " " + contact.familyName
        avatarData  = contact.thumbnailImageData
        for phone in contact.phoneNumbers {
            phoneNumber.append(phone.value.stringValue)
        }
        for mail in contact.emailAddresses {
            email.append(mail.value as String)
        }
    }

    override init() {
        super.init()
    }
}

一个Swift 4.0实现,用于拉入所有联系人

let contactStore = CNContactStore()
var contacts = [CNContact]()
let keys = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName)]
let request = CNContactFetchRequest(keysToFetch: keys)

do {
    try contactStore.enumerateContacts(with: request) { (contact, stop) in
        contacts.append(contact)
    }
} catch {
    print(error.localizedDescription)
}
这将创建一个本地属性来存储联系人,然后通过对
联系人存储
的枚举填充这些联系人

import UIKit
import Contacts
import ContactsUI

override func viewDidLoad() {
    super.viewDidLoad()

    // `contacts` Contains all details of Phone Contacts
    let contacts = self.getContactFromCNContact() 
    for contact in contacts {

        print(contact.middleName)
        print(contact.familyName)
        print(contact.givenName)
    }
}

func getContactFromCNContact() -> [CNContact] {

    let contactStore = CNContactStore()
    let keysToFetch = [
        CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
        CNContactGivenNameKey,
        CNContactMiddleNameKey,
        CNContactFamilyNameKey,
        CNContactEmailAddressesKey,
        ] as [Any]

    //Get all the containers
    var allContainers: [CNContainer] = []
    do {
        allContainers = try contactStore.containers(matching: nil)
    } catch {
        print("Error fetching containers")
    }

    var results: [CNContact] = []

    // Iterate all containers and append their contacts to our results array
    for container in allContainers {

        let fetchPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)

        do {
            let containerResults = try contactStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keysToFetch as! [CNKeyDescriptor])
            results.append(contentsOf: containerResults)

        } catch {
            print("Error fetching results for container")
        }
    }

    return results
}
let contactStore=CNContactStore()
变量触点=[CNContact]()
让键=[
CNContactFormatter.descriptorForRequiredKeys(用于:.fullName),
CNContactPhoneNumbersKey,
CNContactEmailAddressesKey
]如[任何]
let request=CNContactFetchRequest(keystefetch:keys as![CNKeyDescriptor])
做{
尝试contactStore。枚举联系人(使用:请求){
(接触,停止)进入
//包含来自各地的所有统一联系人的数组
contacts.append(contact)
用于contact.phoneNumber中的phoneNumber{
如果let number=phoneNumber.value为?CNPhoneNumber,则let label=phoneNumber.label{
让localizedLabel=CNLabeledValue.localizedString(forLabel:label)
打印(“\(contact.givenName)\(contact.familyName)电话:\(localizedLabel)--\(number.stringValue),电子邮件:\(contact.emailAddresses)”)
}
}
}
打印(联系人)
}抓住{
打印(“无法获取联系人”)
}

请查看我的答案。它基于上面的答案,并进行了某些改进,只需执行以下操作

在pod文件中

source 'https://github.com/CocoaPods/Specs.git'
pod 'PhoneNumberKit', '~> 2.6'
import Contacts
import PhoneNumberKit
import UIKit

override func viewDidLoad() {
    super.viewDidLoad()

    let contactStore = CNContactStore()
    var contacts = [CNContact]()
    let keys = [
        CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
        CNContactPhoneNumbersKey,
        CNContactEmailAddressesKey,
    ] as [Any]
    let request = CNContactFetchRequest(keysToFetch: keys as! [CNKeyDescriptor])
    do {
        try contactStore.enumerateContacts(with: request) {
            contact, _ in
            // Array containing all unified contacts from everywhere
            contacts.append(contact)
            for phoneNumber in contact.phoneNumbers {
                if let number = phoneNumber.value as? CNPhoneNumber, let label = phoneNumber.label {
                    let localizedLabel = CNLabeledValue<CNPhoneNumber>.localizedString(forLabel: label)

                    // Get The Name
                    let name = contact.givenName + " " + contact.familyName
                    print(name)

                    // Get The Mobile Number
                    var mobile = number.stringValue
                    mobile = mobile.replacingOccurrences(of: " ", with: "")

                    // Parse The Mobile Number
                    let phoneNumberKit = PhoneNumberKit()

                    do {
                        let phoneNumberCustomDefaultRegion = try phoneNumberKit.parse(mobile, withRegion: "IN", ignoreType: true)
                        let countryCode = String(phoneNumberCustomDefaultRegion.countryCode)
                        let mobile = String(phoneNumberCustomDefaultRegion.nationalNumber)
                        let finalMobile = "+" + countryCode + mobile
                        print(finalMobile)
                    } catch {
                        print("Generic parser error")
                    }

                    // Get The Email
                    var email: String
                    for mail in contact.emailAddresses {
                        email = mail.value as String
                        print(email)
                    }
                }
            }
        }

    } catch {
        print("unable to fetch contacts")
    }
}
然后运行pod安装

然后在ViewController文件中

source 'https://github.com/CocoaPods/Specs.git'
pod 'PhoneNumberKit', '~> 2.6'
import Contacts
import PhoneNumberKit
import UIKit

override func viewDidLoad() {
    super.viewDidLoad()

    let contactStore = CNContactStore()
    var contacts = [CNContact]()
    let keys = [
        CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
        CNContactPhoneNumbersKey,
        CNContactEmailAddressesKey,
    ] as [Any]
    let request = CNContactFetchRequest(keysToFetch: keys as! [CNKeyDescriptor])
    do {
        try contactStore.enumerateContacts(with: request) {
            contact, _ in
            // Array containing all unified contacts from everywhere
            contacts.append(contact)
            for phoneNumber in contact.phoneNumbers {
                if let number = phoneNumber.value as? CNPhoneNumber, let label = phoneNumber.label {
                    let localizedLabel = CNLabeledValue<CNPhoneNumber>.localizedString(forLabel: label)

                    // Get The Name
                    let name = contact.givenName + " " + contact.familyName
                    print(name)

                    // Get The Mobile Number
                    var mobile = number.stringValue
                    mobile = mobile.replacingOccurrences(of: " ", with: "")

                    // Parse The Mobile Number
                    let phoneNumberKit = PhoneNumberKit()

                    do {
                        let phoneNumberCustomDefaultRegion = try phoneNumberKit.parse(mobile, withRegion: "IN", ignoreType: true)
                        let countryCode = String(phoneNumberCustomDefaultRegion.countryCode)
                        let mobile = String(phoneNumberCustomDefaultRegion.nationalNumber)
                        let finalMobile = "+" + countryCode + mobile
                        print(finalMobile)
                    } catch {
                        print("Generic parser error")
                    }

                    // Get The Email
                    var email: String
                    for mail in contact.emailAddresses {
                        email = mail.value as String
                        print(email)
                    }
                }
            }
        }

    } catch {
        print("unable to fetch contacts")
    }
}
导入联系人
导入电话号码
导入UIKit
重写func viewDidLoad(){
super.viewDidLoad()
让contactStore=CNContactStore()
变量触点=[CNContact]()
让键=[
CNContactFormatter.descriptorForRequiredKeys(用于:.fullName),
CNContactPhoneNumbersKey,
CNContactEmailAddressesKey,
]如[任何]
let request=CNContactFetchRequest(keystefetch:keys as![CNKeyDescriptor])
做{
尝试contactStore。枚举联系人(使用:请求){
联系人,uu in
//包含来自各地的所有统一联系人的数组
contacts.append(contact)
用于contact.phoneNumber中的phoneNumber{
如果let number=phoneNumber.value为?CNPhoneNumber,则let label=phoneNumber.label{
让localizedLabel=CNLabeledValue.localizedString(forLabel:label)
//得到名字
让name=contact.givenName+“”+contact.familyName
印刷品(名称)
//获取手机号码
var mobile=number.stringValue
mobile=mobile.replacingOccurrences(of:,with:)
//解析手机号码
设phoneNumberKit=phoneNumberKit()
做{
让phonenumberrcustomdefaultregion=尝试phoneNumberKit.parse(mobile,with region:“IN”,ignoreType:true)
让countryCode=String(phonenumberrcustomdefaultregion.countryCode)
let mobile=String(phonenumberrcustomdefaultregion.nationalNumber)
让finalMobile=“+”+国家代码+手机
打印(最终移动)
}抓住{
打印(“通用解析器错误”)
}
//收到电子邮件
var电子邮件:String
用于contact.EmailAddresss中的邮件{
email=mail.value作为字符串
打印(电子邮件)
}
}
}
}
}抓住{
打印(“无法获取联系人”)
}
}

请尝试下面的功能,它可以帮助您(Swift 4)


请看这个问题:@Ollie OP正在寻找“联系人框架”的解决方案,而您发布的链接仍然是一个地址簿,我认为这没有帮助。@Christopher关于这个问题的许多解决方案实际上使用了联系人框架。第二个答案给出了详细的解释。非常有用。若我想获取姓名和号码,若用户有多个号码,如何解决这种情况CNContact返回CNPhoneNumbers数组。您可以简单地获取数组中的第一个号码,或者迭代列表并解析电话号码的CNLabeledValue,以找到您想要的号码,例如位于
self.contactStore
comming的“work”或“mobile”