Issue regarding retrieving all email id's from address book in iphone - email

I am newbie to Address book programming. I want to retrieve all email id's from address book.The issue is below code gets the all data for one record(one person). but When i add more than one contact in address book. it crushes without showing any exception.
Any suggestions? Thanks in advance.
self.pastUrls = [[NSMutableArray alloc] init];
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *addresses = (NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);
// you could probably do some kind of enumeration but I'm doing old fashoined way
int i;
for(i = 0; i < [addresses count]; i++) {
ABRecordRef record = [addresses objectAtIndex:i];
ABMultiValueRef multiValue = ABRecordCopyValue(record, kABPersonEmailProperty);
NSLog(#"%#",multiValue);
int count = ABMultiValueGetCount(multiValue);
NSLog(#"%d",count);
int j;
for(j = 0; j < count; j++) {
NSString *label = (NSString *)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(multiValue, i));
NSString *value = (NSString *)ABMultiValueCopyValueAtIndex(multiValue, i);
//NSLog(#"Email for %#: %#", label, value);
[pastUrls addObject:value];
}
}
Regards,
sathish

There are a couple of online tutorials here that should help:
http://iphone.zcentric.com/2008/09/19/access-the-address-book/
https://developer.apple.com/iphone/library/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/100-Introduction/Introduction.html

Apple's Address Book Programming Guide for iOS includes a sample project that will get you started with general principles for accessing address book data, including email addresses.

Related

How to take permission of contact access in iOS5?

I am making an application which is compatible with iOS5 and it I want to take permission before to access the user contact list. In iOS6 I am able to do this but in iOS5 I have not found any code for to this. I am using it to access the contact list -
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef all = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex n = ABAddressBookGetPersonCount(addressBook);
for( int i = 0 ; i < n ; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex(all, i);
ABMultiValueRef *phones = ABRecordCopyValue(ref, kABPersonPhoneProperty);
for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
{
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
//CFRelease(phones);
NSString *phoneNumber = (__bridge NSString *)phoneNumberRef;
CFRelease(phoneNumberRef);
// NSString *s = #"foo/bar:baz.foo";
NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:#"+- *#( )"];
phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"phone number new %#", phoneNumber);
}
}
Please suggest how to do this.
Since the Address Book permission requirement was only recently added as of iOS 6 you don't have to ask for permission.
If you still want to do that then you would simply show an UIAlertView and record the user's choice in NSUserDefaults.
Note though that if the user upgrades from iOS 5 to 6 he would be asked again, so you would have to disable your iOS 5 permission dialog in that case.

Getting twitter user from Address Book

I'm trying to get the Twitter username from a contact in the address book but I'm not able to do it
I'm using this code that I found "googling":
- (NSString*)getTwitterUsernameFromRecord:(ABRecordRef)record {
NSString * twitterUsername = nil;
ABMultiValueRef socials = ABRecordCopyValue(record, kABPersonSocialProfileProperty);
if (!socials) {
return nil;
}
CFIndex socialsCount = ABMultiValueGetCount(socials);
for (int k=0 ; k<socialsCount ; k++) {
CFDictionaryRef socialValue = ABMultiValueCopyValueAtIndex(socials, k);
if(CFStringCompare( CFDictionaryGetValue(socialValue, kABPersonSocialProfileServiceKey), kABPersonSocialProfileServiceTwitter, 0)==kCFCompareEqualTo) {
twitterUsername = (NSString*) CFDictionaryGetValue(socialValue, kABPersonSocialProfileUsernameKey);
}
CFRelease(socialValue);
if(twitterUsername)
break;
}
CFRelease(socials);
return twitterUsername;
}
I've put the if to validate the "socials" array is nil because I was getting exception when trying to get "socials" array count.
I've tried this code in the simulator and in a real device with contacts which twitter info is filled but the "socials" array I get is always nil. I'm getting the wrong property from the record? Any help?
Thank you in advance
your function works for me almost as-is, aside from needing to bridge cast the twitter username (which is just an ARC thing). how are you accessing the address book?
when i use this code to call your function:
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex contactCount = ABAddressBookGetPersonCount(addressBook);
for( int i = 0; i<contactCount; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex(people, i);
NSString *twitterHandle = [self getTwitterUsernameFromRecord:ref];
if (twitterHandle) {
NSLog(#"record %d has twitter name %#", i, twitterHandle);
}
}
i get this console output:
2012-06-26 12:09:40.864 AddressBookTest[2246:707] record 57 has twitter name alexshepard

Using iOS Addressbook api to search exchange contacts

I am developing app where I would like to search for exchange contact by Name (similar to what phone contacts app does), going through AddressBook API of iOS and also searching net I am still not able to understand how can I use iOS address book api to search exchange contact.
I could only find that Address book provided information that an ABSource is searchable but does not provide how to search. If any body can help it is much appreciated. Thank you Very much in advance.. I have been struggling on this for quite a long time now..
I also tried to customize ABPeoplePicker but had no much help.
The approach I took to solving this was to find the ABSource records that I wanted, then use those to get the ABPerson records in the source, then build up some data structures and filter them with NSPredicate. A bit convoluted perhaps but it seems to work.
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook);
CFIndex sourcesCount = CFArrayGetCount(sources);
ABRecordRef sourceToSearch = NULL;
for (CFIndex index = 0; index < sourcesCount; index++)
{
ABRecordRef record = (ABRecordRef)CFArrayGetValueAtIndex(sources, index);
NSNumber *sourceTypeNumber = (__bridge NSNumber *)(CFNumberRef)ABRecordCopyValue(record, kABSourceTypeProperty);
ABSourceType sourceType = [sourceTypeNumber intValue];
if (sourceType == 4) //this was the only source type with people on my phone, I guess you'll use kABSourceTypeExchange instead
{
sourceToSearch = record;
break;
}
}
CFArrayRef peopleInRecord = (CFArrayRef)ABAddressBookCopyArrayOfAllPeopleInSource(addressBook, sourceToSearch);
CFIndex peopleCount = CFArrayGetCount(peopleInRecord);
NSMutableArray *peopleDictionaries = [NSMutableArray array];
for (CFIndex index = 0; index < peopleCount; index++)
{
ABRecordRef personRecord = CFArrayGetValueAtIndex(peopleInRecord, index);
ABRecordID recordID = ABRecordGetRecordID(personRecord);
NSString *personName = (__bridge NSString *)(CFStringRef)ABRecordCopyValue(personRecord, kABPersonFirstNameProperty);
if (personName)
{
NSDictionary *personDictionary = #{ #"recordID" : [NSNumber numberWithInt:recordID], #"name" : personName };
[peopleDictionaries addObject:personDictionary];
}
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K like %#",#"name",#"Kyle"];
NSArray *kyles = [peopleDictionaries filteredArrayUsingPredicate:predicate];
NSLog(#"filtered dictionarys = %#",kyles);
/*
2012-08-27 17:26:24.679 FunWithSO[21097:707] filtered dictionaries = (
{
name = Kyle;
recordID = 213;
}
)*/
//From here, get the recordID instance and go get your ABPerson Records directly from the address book for further manipulation.
Hope this helps, let me know if you have any questions!

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.