Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetching all contacts in ios Swift?

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

like image 762
the_naive Avatar asked Nov 28 '15 16:11

the_naive


People also ask

How do I get all my contacts in Swift?

Swift 4 and 5. 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.

How do I sync contacts in Swift?

Create a new swift file and give it a name “ContactUtility. swift”, follow the same steps as we created CoreDataManager class. Here we will use Contacts library to access contact book, so import contacts and ContactUI framework in the Link Binary with Library of the build Phase section in the project setting.

How do I constrain the number of contacts returned from fetch?

The Contacts framework provides several ways to constrain contacts returned from a fetch, including predefined predicates and the keysToFetch property. CNContact provides predicates for filtering the contacts you want to fetch.

How to access contacts data in an iOS app?

An iOS app linked on or after iOS 10.0 must include in its Info.plist file the usage description keys for the types of data it needs to access or it will crash. To access Contacts data specifically, it must include NSContactsUsageDescription. A partial contact has only some of its property values fetched from a contact store.

What is the contacts framework in iOS?

The Contacts framework is available on all Apple platforms and replaces the Address Book framework in iOS and macOS. The contact class (CNContact) is a thread-safe, immutable value object of contact properties, such as the contact’s name, image, or phone numbers.

Is the contacts framework thread-safe?

Because most apps read contact information without making any changes, this framework is optimized for thread-safe, read-only usage. The Contacts framework is available on all Apple platforms and replaces the Address Book framework in iOS and macOS.


2 Answers

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()     } } 
like image 93
Gurjinder Singh Avatar answered Oct 06 '22 22:10

Gurjinder Singh


Many answers to Contact Framework questions suggest iterating over various containers (accounts). However, Apple's documentation describes a "Unified Contact" as

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

So simplest way to fetch a list of (partial, based on keys) contacts in a single array, would be the following:

      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")     } 
like image 38
Ri_ Avatar answered Oct 06 '22 22:10

Ri_