正在获取 ios Swift 中的所有联系人?
Fetching all contacts in ios Swift?
我知道 ios swift 有一个 Contacts Framework 我可以在其中获取联系人,但我找不到任何方法将所有联系人一起获取,我可以访问每个联系人来自该数组的联系人。所有获取联系人的方法似乎都需要某种条件。有什么方法可以把所有联系人都集中起来吗?
谢谢
// 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")
}
}
Contact Framework 问题的许多答案都建议迭代各种容器(帐户)。但是,Apple 的文档将“统一联系人”描述为
Contacts in different accounts that represent the same person may be automatically linked together. Linked contacts are displayed in OS X and iOS apps as unified contacts. A unified contact is an in-memory, temporary view of the set of linked contacts that are merged into one contact.
By default the Contacts framework returns unified contacts. Each fetched unified contact (CNContact) object has its own unique identifier that is different from any individual contact’s identifier in the set of linked contacts. A refetch of a unified contact should be done with its identifier.
Source
在单个数组中获取(部分,基于键)联系人列表的最简单方法如下:
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。我已经创建了 class 个 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
}
}
在另一个class
中调用上述方法
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.
}
现在,获取电子邮件和 phone 个联系人
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({ [=12=].email.count > 0 }) // getting all email
} else if self.filter == .message {
filterdArray = allContacts.filter({ [=12=].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
}
}
}
PhoneContact 型号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()
}
}
A 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
的枚举来填充这些联系人。
更新 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")
}
请看我的回答,它是在上面的回答基础上做的一些改进,只需执行以下操作
在您的 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")
}
}
请试试下面的功能,对你有帮助(Swift 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
}
复解:
var contacts = [CNContact]()
let keys: [Any] = [
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactImageDataKey,
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactJobTitleKey,
CNContactBirthdayKey,
CNContactPostalAddressesKey
]
let request = CNContactFetchRequest(keysToFetch: keys as! [CNKeyDescriptor])
let contactStore = CNContactStore()
try? contactStore.enumerateContacts(with: request, usingBlock: { contact, _ in
contacts.append(contact)
})
别忘了Info.plist:
NSContactsUsageDescription
我知道 ios swift 有一个 Contacts Framework 我可以在其中获取联系人,但我找不到任何方法将所有联系人一起获取,我可以访问每个联系人来自该数组的联系人。所有获取联系人的方法似乎都需要某种条件。有什么方法可以把所有联系人都集中起来吗?
谢谢
// 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")
}
}
Contact Framework 问题的许多答案都建议迭代各种容器(帐户)。但是,Apple 的文档将“统一联系人”描述为
Contacts in different accounts that represent the same person may be automatically linked together. Linked contacts are displayed in OS X and iOS apps as unified contacts. A unified contact is an in-memory, temporary view of the set of linked contacts that are merged into one contact.
By default the Contacts framework returns unified contacts. Each fetched unified contact (CNContact) object has its own unique identifier that is different from any individual contact’s identifier in the set of linked contacts. A refetch of a unified contact should be done with its identifier. Source
在单个数组中获取(部分,基于键)联系人列表的最简单方法如下:
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。我已经创建了 class 个 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
}
}
在另一个class
中调用上述方法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.
}
现在,获取电子邮件和 phone 个联系人
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({ [=12=].email.count > 0 }) // getting all email
} else if self.filter == .message {
filterdArray = allContacts.filter({ [=12=].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
}
}
}
PhoneContact 型号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()
}
}
A 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
的枚举来填充这些联系人。
更新 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")
}
请看我的回答,它是在上面的回答基础上做的一些改进,只需执行以下操作
在您的 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")
}
}
请试试下面的功能,对你有帮助(Swift 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
}
复解:
var contacts = [CNContact]()
let keys: [Any] = [
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactImageDataKey,
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactJobTitleKey,
CNContactBirthdayKey,
CNContactPostalAddressesKey
]
let request = CNContactFetchRequest(keysToFetch: keys as! [CNKeyDescriptor])
let contactStore = CNContactStore()
try? contactStore.enumerateContacts(with: request, usingBlock: { contact, _ in
contacts.append(contact)
})
别忘了Info.plist:
NSContactsUsageDescription