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

时间:2015-11-28 16:23:18

标签: ios swift cncontact

我知道ios swift有Contacts Framework我可以获取联系人,但我找不到任何方法来获取所有联系人,我可以访问该数组中的每个联系人。获取联系人的所有方法似乎都需要某种条件。有什么方法可以将所有联系人聚集在一起吗?

由于

8 个答案:

答案 0 :(得分:20)

Contact Framework问题的许多答案建议迭代各种容器(帐户)。但是,Apple的文档将“统一联系人”描述为

  

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

     

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

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

    var contacts = [CNContact]()
    let keys = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)]
    let request = CNContactFetchRequest(keysToFetch: keys)

    do {
        try self.contactStore.enumerateContactsWithFetchRequest(request) {             
            (contact, stop) in
            // Array containing all unified contacts from everywhere
            contacts.append(contact)
        }
    } 
    catch {
        print("unable to fetch contacts")
    }

答案 1 :(得分:13)

Swift 4.我创建了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 {
            Debug.Log(message: "Error fetching containers") // you can use print()
        }

        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 {
                Debug.Log(message: "Error fetching containers")
            }
        }
        return results
    }
}

在另一个类中调用上面的方法

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)
        DispatchQueue.main.async {
            self.tableView.reloadData()
          }
        }
    }

PhoneContact Model Class

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

答案 2 :(得分:11)

Swift 4的更新

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, stop) 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)
                print("\(contact.givenName) \(contact.familyName) tel:\(localizedLabel) -- \(number.stringValue), email: \(contact.emailAddresses)")
            }
        }
    }
    print(contacts)
} catch {
    print("unable to fetch contacts")
}

答案 3 :(得分:5)

    // You may add more "keys" to fetch referred to official documentation
    let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName)]

    // The container means 
    // that the source the contacts from, such as Exchange and iCloud
    var allContainers: [CNContainer] = []
    do {
        allContainers = try store.containersMatchingPredicate(nil)
    } catch {
        print("Error fetching containers")
    }

    var contacts: [CNContact] = []

    // Loop the containers
    for container in allContainers {
        let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier)

        do {
            let containerResults = try store.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
            // Put them into "contacts"
            contacts.appendContentsOf(containerResults)
        } catch {
            print("Error fetching results for container")
        }
    }

答案 4 :(得分:2)

一个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)
}

这将创建一个本地属性来存储联系人,然后通过contactStore的枚举填充这些联系人。

答案 5 :(得分:2)

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

在您的pod文件中

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

然后运行pod安装

然后在您的ViewController文件中

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

答案 6 :(得分:0)

请尝试以下功能,对您有帮助

func getContactList() {

  let contacts = self.getContactFromCNContact()

  for contact in contacts {

     //do your stuff with contact 
   } 
}

func getContactFromCNContact() -> [CNContact] {

    let contactStore = CNContactStore()
    let keysToFetch = [
        CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
        CNContactIdentifierKey,
        CNContactNamePrefixKey,
        CNContactGivenNameKey,
        CNContactMiddleNameKey,
        CNContactFamilyNameKey,
        CNContactPreviousFamilyNameKey,
        CNContactNameSuffixKey,
        CNContactNicknameKey,
        CNContactOrganizationNameKey,
        CNContactDepartmentNameKey,
        CNContactJobTitleKey,
        CNContactPhoneticGivenNameKey,
        CNContactPhoneticMiddleNameKey,
        CNContactPhoneticFamilyNameKey,
        CNContactBirthdayKey,
        CNContactNonGregorianBirthdayKey,
        CNContactNoteKey,
        CNContactImageDataKey,
        CNContactThumbnailImageDataKey,
        CNContactImageDataAvailableKey,
        CNContactTypeKey,
        CNContactPhoneNumbersKey,
        CNContactEmailAddressesKey,
        CNContactPostalAddressesKey,
        CNContactDatesKey,
        CNContactUrlAddressesKey,
        CNContactRelationsKey,
        CNContactSocialProfilesKey,
        CNContactInstantMessageAddressesKey] 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 
  }

答案 7 :(得分:0)

请尝试以下功能,对您有帮助(快速4)

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
}