Retrive data of address book and display in string format [closed] - iphone

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Hi I am developing an apps in that I got one requirement where I have a button action method when I click the button I should retrive whole address book contacts and display in the form of string how do i do this can anyone tel me with code. I am not able to this from couple of days.
I dont want to navigate using ABPeoplePickerNavigationController and access it
,What all I need is click on button access all contact and display in the form of string.

Try this it works for iOS 6 as well as iOS 5.0 or older:
First add the following frameworks in Link Binary With Libraries
AddressBookUI.framework
AddressBook.framework
Them Import
#import <AddressBook/ABAddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
Then use the following code
ABAddressBookRef addressBook = ABAddressBookCreate();
__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];
}
// Get the contacts.
- (void)getContactsWithAddressBook:(ABAddressBookRef )addressBook {
NSArray *arrayOfPeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger index = 0;
NSMutableArray *firstNames = [[NSMutableArray alloc] init];
for(index = 0; index <= ([arrayOfPeople count] - 1); index++){
ABRecordRef currentPerson = (__bridge ABRecordRef)[arrayOfPeople objectAtIndex:index];
NSString *currentFirstName = (__bridge_transfer NSString *)ABRecordCopyValue(currentPerson, kABPersonFirstNameProperty);
// If first name is empty then don't add to the array
if (![currentFirstName length] == 0) {
[firstNames addObject: currentFirstName];
}
}
//OPTIONAL: Use the following line to sort the first names alphabetically
NSArray *sortedFirstNames = [firstNames sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSLog(#"Total Count = %d \n Sorted By Name = %#", [sortedFirstNames count], sortedFirstNames);
}
I tested this and it works.

try this for .
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
for(id person in people){
NSString *name = [NSString stringWithFormat:#"%# %#",(NSString *)ABRecordCopyValue( person, kABPersonFirstNameProperty ),(NSString *)ABRecordCopyValue( person, kABPersonLastNameProperty )];
//fetch multiple phone nos.
ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty);
for (CFIndex j=0; j < ABMultiValueGetCount(multi); j++) {
NSString* phone = (NSString*)ABMultiValueCopyValueAtIndex(multi, j);
[numbersArray addObject:phone];
[phone release];
}
/fetch multiple email ids.
ABMultiValueRef multiemail = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex j=0; j < ABMultiValueGetCount(multiemail); j++) {
NSString* email = (NSString*)ABMultiValueCopyValueAtIndex(multiemail, j);
NSLog(#"Email=%#",email);
}
}
and you have to alloc your array before you use. in viewDidLoad method write this for alloc array
numbersArray=[[NSMutableArray alloc] init];

Related

fetching only mobile section record (not from iphone, home label etc) from addressbook?

How do I fetch only mobile section record from addressbook in ios?
I want to add only one record to my array that is fetched from mobile section record.
How do I do that. I am getting all the phone property records. but I need to get only mobile section record.
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(myAddressBook);
NSLog(#"allpeople%#", allPeople);
for (id record in allPeople) {
CFTypeRef phoneProperty = ABRecordCopyValue((ABRecordRef)record, kABPersonPhoneProperty);
NSArray *phones = (NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
NSLog(#"phones %#",phones);
CFRelease(phoneProperty);
NSMutableDictionary *newRecord = [[NSMutableDictionary alloc] init];
NSMutableString *newPhone = [[NSMutableString alloc] init];
for (NSString *phone in phones) {
if(![newPhone isEqualToString:#""])
[newPhone appendString:#", "];
[newPhone appendString:phone];
}
You can try something like this..
ABMultiValueRef phoneNumbers = ABRecordCopyValue(abPerson, kABPersonPhoneProperty);
if (phoneNumbers) {
CFIndex numberOfPhoneNumbers = ABMultiValueGetCount(phoneNumbers);
for (CFIndex i = 0; i < numberOfPhoneNumbers; i++) {
NSString *phone = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, i);
CFStringRef label = ABMultiValueCopyLabelAtIndex(phoneNumbers, i);
if (label) {
if (CFEqual(label, kABPersonPhoneMobileLabel)) {
primaryPhoneText.text = phone;
} else {
}
CFRelease(label);
[allPhones addObject:phone]; // allPhones is an array here.
}
}
CFRelease(phoneNumbers);
}
Hope this will help you out..
Enjoy coding..

iPhone address book problem

I'm having a bit of an issue with using the address book to get the names of the contacts from the device into my own contacts view within my application.
The code I have works fine on the emulator but I when tested on an iPhone 4 it will crash, the application seems to work fine if there are two or less contacts but 3 or more and the application crashes.
Here is the code I am using to get the names of contacts into an array.
ABAddressBookRef addressBook;
bool wantToSaveChanges = YES;
bool didSave;
CFErrorRef error = NULL;
addressBook = ABAddressBookCreate();
listOfContacts = [[NSMutableArray alloc]init];
int i;
int len = (int) ABAddressBookGetPersonCount(addressBook);
for(i = 1; i< (len+1); i++){
ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, (ABRecordID) i);
NSString* name = (NSString *)ABRecordCopyCompositeName(person);
ABMultiValueRef number = (NSString *)ABRecordCopyValue(person,kABPersonPhoneProperty);
NSString *mobileNum = (NSString *)ABMultiValueCopyValueAtIndex(number, 0 );
NSLog(#"Name = %#", name);
NSLog(#"Number = %#", mobileNum);
[listOfContacts addObject:name];
[name release];
[mobileNum release];
}
if(ABAddressBookHasUnsavedChanges(addressBook)){
if(wantToSaveChanges){
didSave = ABAddressBookSave(addressBook, &error);
if(!didSave){
//Error
}
}
else{
ABAddressBookRevert(addressBook);
}
}
When it crashes this is the line that gets highlighted in Xcode:
NSString* name = (NSString *)ABRecordCopyCompositeName(person);
And the error states:
Thread 1: Program received signal: "EXC_BAD_ACCESS"
Can anyone see what the problem might be? I dont understand why it would work on the emulator but not on the device? And also why it works for up to two contacts but not 3 or more??
Just a guess:
ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, (ABRecordID) i);
This line looks fishy for me. I doubt that the record IDs are numbered from 1 to whatever. Especially if you have deleted an entry.
This would explain why it works on the simulator, I guess you just added some test contacts and never deleted one.
Here is how I solved it:
(Note how I make sure to call only active records, also I created a customized Contact class)
This code takes care of edge case like: email/phone doesn't exist, or exists more than once...
+(NSArray *)getAddressBook{
ABAddressBookRef addressBook;
bool wantToSaveChanges = YES;
bool didSave;
CFErrorRef error = NULL;
addressBook = ABAddressBookCreate();
NSMutableArray *listOfContacts = [[NSMutableArray alloc]init];
CFArrayRef array=ABAddressBookCopyArrayOfAllPeople(addressBook);
int len=CFArrayGetCount(array);
for (int i = 0; i<len; i++){
ABRecordRef person = CFArrayGetValueAtIndex(array, i);
if (ABRecordGetRecordType(person)==kABPersonType){
NSString *firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
ABMultiValueRef emails = (ABMultiValueRef)ABRecordCopyValue(person,kABPersonEmailProperty);
ABMultiValueRef numbers = (ABMultiValueRef)ABRecordCopyValue(person,kABPersonPhoneProperty);
int sumEmails=ABMultiValueGetCount(emails);
int sumNumbers=ABMultiValueGetCount(numbers);
for (int j=0; j<(sumNumbers>sumEmails?sumNumbers:sumEmails); j++) {
ACL_AB_Contact *contact=[[ACL_AB_Contact alloc]initWithFirstName:firstName LastName:lastName];
if (j<sumEmails){
contact.emailAddress=(NSString *)ABMultiValueCopyValueAtIndex(emails,j);
}
if (j<sumNumbers){
contact.phoneNumber=(NSString *)ABMultiValueCopyValueAtIndex(numbers,j);
}
[contact logContact];
[listOfContacts addObject:contact];
[contact release];
}
}
}
if(ABAddressBookHasUnsavedChanges(addressBook)){
if(wantToSaveChanges){
didSave = ABAddressBookSave(addressBook, &error);
if(!didSave){
//Error
}
}
else{
ABAddressBookRevert(addressBook);
}
}
return [listOfContacts autorelease];
}
The record IDs are dynamic. It means that if you add 2 contacts and then remove the first, you will have only a contact with id "2". So I wouln't use a for statement to get through the contacts. Follow the Address Book Programming Guide

How to use ABAddressBookRef for iPhone application?

I want reference of my address book in one of iPhone application. I have used below code. But its showing [people count] = 0.
I have 3-4 contacts on my addressbook application still [people count] returns zero.
Is anything more, I am missing here?
Code is:
ABAddressBookRef addressBook = ABAddressBookCreate();
NSMutableArray *people = [[[(NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook) autorelease] mutableCopy]autorelease];
[people sortUsingFunction:(int (*)(id,id,void*)) ABPersonComparePeopleByName context:(void*)ABPersonGetSortOrdering()];
NSLog(#"count..%i",[people count]);
for(int i = 0 ; i < [people count]; i++){
ABRecordRef person = [people objectAtIndex:i];
//get phone no fill phone no into array
ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty);
if(multi!=NULL && ABMultiValueGetCount(multi)>0) {
NSLog(#"in value..");
}
else {
NSLog(#"no value");
}
}
Thank You
try that -
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people;
people = ABAddressBookCopyArrayOfAllPeople(HiByeGroup);
if (people){
CFArrayCreateMutableCopy(kCFAllocatorDefault,CFArrayGetCount(people),people);
NSInteger numberOfPersonsInAB=CFArrayGetCount(peopleMutable);
for (int i =0; i< numberOfPersonsInAB; i++) {
//your code
}
CFRelease(people);
UPdate
As Jamon Holmgren noted, this answer is old and ABAddressBookCreate() is deprecated in iOS6. You need to use ABAddressBookCreateWithOptions() instead.
GOOD LUCK
Just follow given code over here. A perfect example to interact with ABAddressBook.

Search ABAddressbook iOS SDK

I want to search the iPhone address book for a specific phone number, and then retrieve the contact name. I am currently looping through all contacts and extracting the multivalue properties and comparing against the value. This is taking way too much time. I have read the Apple addressbook guide, and they say:
"accomplish other kinds of searches, use the function
ABAddressBookCopyArrayOfAllPeople and then filter the results using
the NSArray method filteredArrayUsingPredicate:."
Can anyone give me an example on how to exactly do that?
Thanks.
If you want to do a search in the contacts with phone number, then I will tell you one suggestion.
1.Get all contacts
NSArray *thePeoples = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
2.Create another array(records) from the contacts array(thePeoples),
records:[
record1, record2, ....recordN ]
record: {name:"myContactName",
phoneNumber:"1234567890"}
3.Search the mutableArray(records) with predicate.
NSPredicate * myPredicate = [NSPredicate predicateWithFormat:#"record.phoneNumber contains %#",string];
NSArray * filteredArray = [records filteredArrayUsingPredicate:myPredicate];
This is just a simple example to your solution, and remember phoneNumber is a multiValue field. So we will include an array as phone number in the model class variable.
The following method will return an array that contains all of the contacts that have the given phone number. This method took 0.02 seconds to search 250 contacts on my iPhone 5 running iOS7.
#import <AddressBook/AddressBook.h>
-(NSArray *)contactsContainingPhoneNumber:(NSString *)phoneNumber {
/*
Returns an array of contacts that contain the phone number
*/
// Remove non numeric characters from the phone number
phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:#""];
// Create a new address book object with data from the Address Book database
CFErrorRef error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (!addressBook) {
return [NSArray array];
} else if (error) {
CFRelease(addressBook);
return [NSArray array];
}
// Requests access to address book data from the user
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {});
// Build a predicate that searches for contacts that contain the phone number
NSPredicate *predicate = [NSPredicate predicateWithBlock: ^(id record, NSDictionary *bindings) {
ABMultiValueRef phoneNumbers = ABRecordCopyValue( (__bridge ABRecordRef)record, kABPersonPhoneProperty);
BOOL result = NO;
for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
NSString *contactPhoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
contactPhoneNumber = [[contactPhoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:#""];
if ([contactPhoneNumber rangeOfString:phoneNumber].location != NSNotFound) {
result = YES;
break;
}
}
CFRelease(phoneNumbers);
return result;
}];
// Search the users contacts for contacts that contain the phone number
NSArray *allPeople = (NSArray *)CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
NSArray *filteredContacts = [allPeople filteredArrayUsingPredicate:predicate];
CFRelease(addressBook);
return filteredContacts;
}
Use This. this is my code.
Make Array for searching.
NSLog(#"=====Make People Array with Numbers. Start.");
peopleWithNumber = [[NSMutableDictionary alloc] init];
for (int i=0; i < [people count]; i++) {
NSInteger phoneCount = [self phoneCountAtIndex:i];
if (phoneCount != 0) {
NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init];
for (int j=0 ; j < phoneCount ; j++) {
[phoneNumbers addObject:[self phoneNumberAtIndex:i phoneIndex:j]];
}
[peopleWithNumber addEntriesFromDictionary:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSArray arrayWithArray:phoneNumbers], [self fullNameAtIndex:i], nil]];
}
}
NSLog(#"=====Make People Array with Numbers. End.\n");
Searching method. it(peopleWithNumber) would be faster than using array(people)
"NSArray *people = (NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);"
- (NSArray *)searchNamesByNumber:(NSString *)number {
NSString *predicateString = [NSString stringWithFormat:#"%#[SELF] contains '%#'",#"%#",number];
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:predicateString,peopleWithNumber,number];
NSArray *names = [[peopleWithNumber allKeys] filteredArrayUsingPredicate:searchPredicate];
return names;
}
You cannot use a predicateWithFormat with an array of ABRecordRef opaque types. But you can use predicateWithBlock:
[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
ABRecordRef person=(__bridge ABRecordRef)evaluatedObject;
CFTypeRef theProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSArray *phones = (__bridge_transfer NSArray *) ABMultiValueCopyArrayOfAllValues(theProperty);
CFRelease(theProperty);
BOOL result=NO;
for (NSString *value in phones) {
if ([value rangeOfString:#"3"].location!=NSNotFound) {
result=YES;
break;
}
}
return result;
}];

ABAddressBook store values in NSDictionary

I have an app that displays ABAddressBook contacts in a UITableView. Currently I'm reading the contacts into an NSDictionary, however this appears to crash for some users, which I suspect is a memory issue.
Is there another approach to display ABAddressBook contacts in a UITableView without either first storing them in an NSDictionary or using ABPeoplePicker?
A different way using ARC:
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef addressBookData = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex count = CFArrayGetCount(addressBookData);
NSMutableArray *contactsArray = [NSMutableArray new];
for (CFIndex idx = 0; idx < count; idx++) {
ABRecordRef person = CFArrayGetValueAtIndex(addressBookData, idx);
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
if (firstName) {
NSDictionary *dict = [NSDictionary dictionaryWithObject:firstName ForKey:#"name"];
[contactsArray addObject:dict];
}
}
CFRelease(addressBook);
CFRelease(addressBookData);
You can use following way,
ABAddressBookRef ab = ABAddressBookCreateWithOptions(NULL, NULL);
NSArray *arrTemp = (NSArray *)ABAddressBookCopyArrayOfAllPeople(ab);
The above 2 lines will create an array for all your contacts on the iPhone.
Now whatever property of a contact you want to display you can display by using the below code. For example, I want to display the first name of all contacts and then create one Mutable array called it arrContact.
NSMutableArray *arrContact = [[NSMutableArray alloc] init];
for (int i = 0; i < [arrTemp count]; i++)
{
NSMutableDictionary *dicContact = [[NSMutableDictionary alloc] init];
NSString *str = (NSString *) ABRecordCopyValue([arrTemp objectAtIndex:i], kABPersonFirstNameProperty);
#try
{
[dicContact setObject:str forKey:#"name"];
}
#catch (NSException * e) {
[dicContact release];
continue;
}
[arrContact addObject:dicContact];
[dicContact release];
}
Now just display it using the arrContact array in a table view..
Same as Abizern's answer, but if you want to display full names that are localized, use ABRecordCopyCompositeName. (In English names are "First Last", but in Chinese names are "LastFirst").
ABRecordRef person = CFArrayGetValueAtIndex(addressBookData, idx);
NSString *fullName = (__bridge_transfer NSString *)ABRecordCopyCompositeName(person);//important for localization