Get a List of All Contacts on Ios

Get a list of all contacts on iOS

Perhaps ABPerson function ABAddressBookCopyArrayOfAllPeople might do?

Example:

ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );

for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
...
}

Fetching all contacts in ios Swift?

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

Retrieve all contacts phone numbers in iOS

Try this it works for iOS 6 as well as iOS 5.0 or older:

Sample Project Demo

First add the following frameworks in Link Binary With Libraries

  • AddressBookUI.framework
  • AddressBook.framework

Then Import

#import 
#import

Then use the following code

Requesting permission to access address book

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

__block BOOL accessGranted = NO;

if (&ABAddressBookRequestAccessWithCompletion != NULL) { // We are on iOS 6
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(semaphore);
});

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_release(semaphore);
}

else { // We are on iOS 5 or Older
accessGranted = YES;
[self getContactsWithAddressBook:addressBook];
}

if (accessGranted) {
[self getContactsWithAddressBook:addressBook];
}

Retrieving contacts from addressbook

// Get the contacts.
- (void)getContactsWithAddressBook:(ABAddressBookRef )addressBook {

contactList = [[NSMutableArray alloc] init];
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

for (int i=0;i < nPeople;i++) {
NSMutableDictionary *dOfPerson=[NSMutableDictionary dictionary];

ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);

//For username and surname
ABMultiValueRef phones =(__bridge ABMultiValueRef)((__bridge NSString*)ABRecordCopyValue(ref, kABPersonPhoneProperty));

CFStringRef firstName, lastName;
firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
[dOfPerson setObject:[NSString stringWithFormat:@"%@ %@", firstName, lastName] forKey:@"name"];

//For Email ids
ABMutableMultiValueRef eMail = ABRecordCopyValue(ref, kABPersonEmailProperty);
if(ABMultiValueGetCount(eMail) > 0) {
[dOfPerson setObject:(__bridge NSString *)ABMultiValueCopyValueAtIndex(eMail, 0) forKey:@"email"];

}

//For Phone number
NSString* mobileLabel;

for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++) {
mobileLabel = (__bridge NSString*)ABMultiValueCopyLabelAtIndex(phones, j);
if([mobileLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel])
{
[dOfPerson setObject:(__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, j) forKey:@"phone"];
}
else if ([mobileLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel])
{
[dOfPerson setObject:(__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, j) forKey:@"phone"];
break ;
}

}
[contactList addObject:dOfPerson];

}
NSLog(@"Contacts = %@",contactList);
}

To retrive other information

// All Personal Information Properties
kABPersonFirstNameProperty; // First name - kABStringPropertyType
kABPersonLastNameProperty; // Last name - kABStringPropertyType
kABPersonMiddleNameProperty; // Middle name - kABStringPropertyType
kABPersonPrefixProperty; // Prefix ("Sir" "Duke" "General") - kABStringPropertyType
kABPersonSuffixProperty; // Suffix ("Jr." "Sr." "III") - kABStringPropertyType
kABPersonNicknameProperty; // Nickname - kABStringPropertyType
kABPersonFirstNamePhoneticProperty; // First name Phonetic - kABStringPropertyType
kABPersonLastNamePhoneticProperty; // Last name Phonetic - kABStringPropertyType
kABPersonMiddleNamePhoneticProperty; // Middle name Phonetic - kABStringPropertyType
kABPersonOrganizationProperty; // Company name - kABStringPropertyType
kABPersonJobTitleProperty; // Job Title - kABStringPropertyType
kABPersonDepartmentProperty; // Department name - kABStringPropertyType
kABPersonEmailProperty; // Email(s) - kABMultiStringPropertyType
kABPersonBirthdayProperty; // Birthday associated with this person - kABDateTimePropertyType
kABPersonNoteProperty; // Note - kABStringPropertyType
kABPersonCreationDateProperty; // Creation Date (when first saved)
kABPersonModificationDateProperty; // Last saved date

// All Address Information Properties
kABPersonAddressProperty; // Street address - kABMultiDictionaryPropertyType
kABPersonAddressStreetKey;
kABPersonAddressCityKey;
kABPersonAddressStateKey;
kABPersonAddressZIPKey;
kABPersonAddressCountryKey;
kABPersonAddressCountryCodeKey;

Further Reference Read Apple Docs

UPDATE:
You need to add description about why you need to access the contacts in you Apps-Info.plist

Privacy - Contacts Usage Description

OR

NSContactsUsageDescription
Write the reason why your app needs the contact.

For getting the user image.

UIImage *contactImage;
if(ABPersonHasImageData(ref)){
contactImage = [UIImage imageWithData:(__bridge NSData *)ABPersonCopyImageData(ref)];
}

NOTE:

The AddressBook framework is deprecated in iOS 9 and replaced with the new and improved Contacts Framework

How to fetch all contacts record in iOS 9 using Contacts Framework

Both other answers do only load contacts from the container with the defaultContainerIdentifier. In a scenario, where the user has more than one container (i.e. an Exchange and an iCloud account which both are used to store contacts), this would only load the contacts from the account that is configured as the default. Therefore, it would not load all contacts as requested by the author of the question.

What you'll probably want to do instead is getting all the containers and iterate over them to extract all contacts from each of them. The following code snippet is an example of how we do it in one of our apps (in Swift):

lazy var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]

// Get all the containers
var allContainers: [CNContainer] = []
do {
allContainers = try contactStore.containersMatchingPredicate(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.predicateForContactsInContainerWithIdentifier(container.identifier)

do {
let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
results.appendContentsOf(containerResults)
} catch {
print("Error fetching results for container")
}
}

return results
}()

How do I get a list of the user's contacts in iOS 6?

In ios6 you need to ask for permission to read the AddressBook, otherwise you'll get nil. Use something like this:

- (BOOL)askContactsPermission {
__block BOOL ret = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS6

dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRef addressBook = ABAddressBookCreate();
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
ret = granted;
dispatch_semaphore_signal(sema);
});
if (addressBook) {
CFRelease(addressBook);
}

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
}
else { // we're on iOS5 or older
ret = YES;
}

return ret;
}

If this method returns NO, bad luck, you won't be able to access the AB. I'm locking with a semaphore here because I don't want to continue with my app if the user does not allow the AB. There other methods, just check the API.

Can I get a phone contacts list with JavaScript?

You can't access phone contacts with PWA, native app is the only way to do that.

List of avaliable features is can be found here here, for contacts, check the "Operating System" section

Fetch list of iOS contacts based on the organization name or the jobtitle

I don't think so you can fetch the contacts from CNContact store by just giving organization name or job title in predicate. You should include organization name and job title in keys to fetch and then iterate the contact list again. Check the code snippet. I hope it helps. Thanks.

func fetchContacts()
{
let contactStore = CNContactStore()
var allContainers : [CNContainer] = []
var allContacts : [CNContact] = []

//you can use one of these/ all keys to filter contacts
let keysToFetch = [CNContactGivenNameKey, CNContactOrganizationNameKey, CNContactJobTitleKey]
var OrganizationArray = [CNContact]()
do{
// _______________ Fetch all the Containers_________________________________
allContainers = try contactStore.containersMatchingPredicate(nil)

}
catch{
print(error)
}
for container in allContainers{
let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier)
do{
//____________Fetch all the contacts corresponding to every Container______
let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
// allContacts.appendContentsOf(containerResults)


for contactRec in containerResults {
if contactRec.organizationName != "" {
OrganizationArray.append(contactRec)
}

}

}
catch{
print(error)
}
}
}

Get only new/modified phone contacts from iPhone

You can save contacts identifier and import date in local storage like SQLite. And when you receive contacts update notification, you can send saved date of respective updated contact and also update date in SQLite with received notification timestamp(date).

iOS Contacts How to Fetch contact by phone Number

The problem with your implementation is that you access the address book in every search you are making.

If instead you will hold in-memory the address book content after the first access you will not reach this high CPU usage.

  1. First hold a lazy var in your controller that will hold the address book content:

    lazy var contacts: [CNContact] = {
    let contactStore = CNContactStore()
    let keysToFetch = [
    CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
    CNContactEmailAddressesKey,
    CNContactPhoneNumbersKey,
    CNContactImageDataAvailableKey,
    CNContactThumbnailImageDataKey]

    // Get all the containers
    var allContainers: [CNContainer] = []
    do {
    allContainers = try contactStore.containersMatchingPredicate(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.predicateForContactsInContainerWithIdentifier(container.identifier)

    do {
    let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
    results.appendContentsOf(containerResults)
    } catch {
    print("Error fetching results for container")
    }
    }

    return results
    }()

    1. Iterate through the in-memory array when you are looking for a contact with a specific phone number:

    .

       func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] {
    var result: [CNContact] = []

    for contact in self.contacts {
    if (!contact.phoneNumbers.isEmpty) {
    let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
    for phoneNumber in contact.phoneNumbers {
    if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber {
    let phoneNumberString = phoneNumberStruct.stringValue
    let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
    if phoneNumberToCompare == phoneNumberToCompareAgainst {
    result.append(contact)
    }
    }
    }
    }
    }

    return result
    }

I tested it with a very big address book, it works smoothly.

Here is the entire view controller patched together for reference.

import UIKit
import Contacts

class ViewController: UIViewController {

lazy var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]

// Get all the containers
var allContainers: [CNContainer] = []
do {
allContainers = try contactStore.containersMatchingPredicate(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.predicateForContactsInContainerWithIdentifier(container.identifier)

do {
let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
results.appendContentsOf(containerResults)
} catch {
print("Error fetching results for container")
}
}

return results
}()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

let contact = searchForContactUsingPhoneNumber("(555)564-8583")
print(contact)
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] {

var result: [CNContact] = []

for contact in self.contacts {
if (!contact.phoneNumbers.isEmpty) {
let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
for phoneNumber in contact.phoneNumbers {
if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber {
let phoneNumberString = phoneNumberStruct.stringValue
let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
if phoneNumberToCompare == phoneNumberToCompareAgainst {
result.append(contact)
}
}
}
}
}

return result
}
}

I used flohei's answer for the lazy var part.



Related Topics



Leave a reply



Submit