So far I saw methods to get multiple phone numbers if I show a picker so user can select people and then get the phone number. What I want is retrieving all contacts
Sure you can. First you'll need to get the user permission for doing so. If you won't the user will have to manually authorize your app from the settings. There's a great example on how to retrieve all phone numbers, names, addresses etc' here.
AddressBook.framework
---> Apple introduced
Here is uploaded Code using latest frameworks.
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
Then Import
#import <AddressBook/ABAddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
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
<key>NSContactsUsageDescription</key>
<string>Write the reason why your app needs the contact.</string>
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
Get permission to the address book or notify the user that the need to change the permission in their settings.
CGFloat iOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if(iOSVersion >= 6.0) {
// Request authorization to Address Book
addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
//start importing contacts
if(addressBookRef) CFRelease(addressBookRef);
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
// The user has previously given access, add the contact
//start importing contacts
if(addressBookRef) CFRelease(addressBookRef);
}
else {
// The user has previously denied access
// Send an alert telling user to change privacy setting in settings app
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unable to Access" message:@"Grant us access now!" delegate:self cancelButtonTitle:@"Not Now" otherButtonTitles:@"I'll Do It!", nil];
[alert show];
if(addressBookRef) CFRelease(addressBookRef);
}
} else {
addressBookRef = ABAddressBookCreate();
//start importing contacts
if(addressBookRef) CFRelease(addressBookRef);
}
Get the records
CFArrayRef records = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSArray *contacts = (__bridge NSArray*)records;
CFRelease(records);
for(int i = 0; i < contacts.count; i++) {
ABRecordRef record = (__bridge ABRecordRef)[contacts objectAtIndex:i];
}
Get the phone number
ABMultiValueRef phonesRef = ABRecordCopyValue(recordRef, kABPersonPhoneProperty);
if(phonesRef) {
count = ABMultiValueGetCount(phonesRef);
for(int ix = 0; ix < count; ix++){
CFStringRef typeTmp = ABMultiValueCopyLabelAtIndex(phonesRef, ix);
CFStringRef numberRef = ABMultiValueCopyValueAtIndex(phonesRef, ix);
CFStringRef typeRef = ABAddressBookCopyLocalizedLabel(typeTmp);
NSString *phoneNumber = (__bridge NSString *)numberRef;
NSString *phoneType = (__bridge NSString *)typeRef;
if(typeTmp) CFRelease(typeTmp);
if(numberRef) CFRelease(numberRef);
if(typeRef) CFRelease(typeRef);
}
CFRelease(phonesRef);
}
Keep in mind, some people have 20,000 contacts in their phone. If you plan on doing this, you'll probably have to multithread the process.