I am aware of the ios swift has a Contacts Framework where I can fetch contacts, but I cannot find any method to fetch all the contacts together where I can access each of the contacts from that array. All methods for fetching contacts seems to require some sort of conditions. Is there any method where I can get all the contacts together?
Thanks
Swift 4 and 5. I have create class PhoneContacts. Please add NSContactsUsageDescription key to your info.plist file
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
}
}
The calling to above method in another 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.
}
Now, Get email and phone of contacts
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
}
}
}
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()
}
}