Some of our app store users are reporting a crash while searching their address book.
I'm pretty lost here cause I can't reproduce this issue.
Is there anything wrong with how I'm querying the address book ? Thanks!!
+ (NSDictionary *) scanAddressBook
{
#if TARGET_OS_IPHONE
NSUInteger i;
CFIndex index;
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *people = (NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);
if ( people==nil || (people && ([people count] == 0)))
{
TRACE_LOG(#"scanAddressBook ", #"NO ADDRESS BOOK ENTRIES TO SCAN");
if(people) [people release];
CFRelease(addressBook);
return nil;
}
NSMutableArray *numbersArray = [NSMutableArray new];
NSMutableArray *mailsArray = [NSMutableArray new];
for ( i=0; i<[people count]; i++ )
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
ABRecordRef person = (ABRecordRef)[people objectAtIndex:i];
NSMutableDictionary *phoneDictionary = [NSMutableDictionary new];
CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString* log =[NSString stringWithFormat:#"-----CONTACT ENTRY -> %# : %#", firstName, lastName ];
TRACE_LOG(#"scanAddressBook",log);
NSString *userName = #"NoName";
if (firstName && lastName)
userName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
else if (firstName)
userName = [NSString stringWithFormat:#"%#", firstName];
else if (lastName)
userName = [NSString stringWithFormat:#"%#", lastName];
if(firstName) CFRelease(firstName);
if(lastName) CFRelease(lastName);
//
// Phone Numbers
//
ABMutableMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex phoneNumberCount = ABMultiValueGetCount( phoneNumbers );
for ( index=0; index<phoneNumberCount; index++ )
{
CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex( phoneNumbers, index);
CFStringRef phoneNumberValue = ABMultiValueCopyValueAtIndex( phoneNumbers, index);
CFStringRef phoneNumberLocalizedLabel = ABAddressBookCopyLocalizedLabel( phoneNumberLabel );
// converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"
// Find the ones you want here
//
NSString* log =[NSString stringWithFormat:#"-----PHONE ENTRY -> %# : %#", phoneNumberLocalizedLabel, phoneNumberValue ];
TRACE_LOG(#"scanAddressBook",log);
if (![NetworkingUtils validatePhoneNumber:(NSString *)phoneNumberValue]) {
NSLog(#"invalid phone number: %#",phoneNumberValue);
CFRelease(phoneNumberLocalizedLabel);
CFRelease(phoneNumberLabel);
CFRelease(phoneNumberValue);
continue;
}
[phoneDictionary setObject:(NSString *)phoneNumberValue forKey:InviteUserDataNumberKeyID];
[phoneDictionary setObject:(NSString *)phoneNumberLocalizedLabel forKey:InviteUserDataNumberTypeKeyID];
[phoneDictionary setObject:(NSString *)userName forKey:InviteUserDataNameTypeKeyID];
CFRelease(phoneNumberLocalizedLabel);
CFRelease(phoneNumberLabel);
CFRelease(phoneNumberValue);
NSMutableDictionary *copyPhoneDict = [phoneDictionary copy];
[numbersArray addObject:copyPhoneDict];
[copyPhoneDict release];
}
CFRelease(phoneNumbers);
[phoneDictionary release];
NSMutableDictionary *mailDictionary = [NSMutableDictionary new];
ABMutableMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
CFIndex mailsNumberCount = ABMultiValueGetCount( emails );
for ( index=0; index < mailsNumberCount; index++ )
{
CFStringRef emailValue = ABMultiValueCopyValueAtIndex( emails,index);
// converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"
// Find the ones you want here
//
NSString* log =[NSString stringWithFormat:#"-----EMAIL ENTRY -> : %#", emailValue ];
TRACE_LOG(#"scanAddressBook",log);
if (![NetworkingUtils validateEmail:(NSString *)emailValue]) {
NSLog(#"invalid email address: %#",(NSString *)emailValue);
if (emailValue) {
CFRelease(emailValue);
}
continue;
}
[mailDictionary setObject:(NSString *)emailValue forKey:InviteUserDataMailKeyID];
[mailDictionary setObject:(NSString *)#"email" forKey:InviteUserDataMailTypeKeyID];
[mailDictionary setObject:(NSString *)userName forKey:InviteUserDataMailOwnerKeyID];
if (emailValue) {
CFRelease(emailValue);
}
NSMutableDictionary *copyMailDict = [mailDictionary copy];
[mailsArray addObject:copyMailDict];
[copyMailDict release];
}
if(emails) CFRelease(emails);
[mailDictionary release];
[pool drain];
}
NSString *countryCode = [[NSUserDefaults standardUserDefaults] objectForKey:RequestUserCountryCodeKeyID];
if (!countryCode) {
NSLocale *locale = [NSLocale currentLocale];
NSString *aCode = [locale objectForKey: NSLocaleCountryCode];
countryCode = [[NetworkingUtils codesByCountryCode] objectForKey:aCode];
}
NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [[numbersArray copy] autorelease], InviteUsersNumbersArrayKeyID,
[[mailsArray copy] autorelease], InviteUsersMailsArrayKeyID,
countryCode, RequestUserCountryCodeKeyID, nil];
[numbersArray release];
[mailsArray release];
[people release];
CFRelease(addressBook);
return aDictionary;
#else
return nil ;
#endif
}
CFRelease() will crash if you provide a NULL value. I see most of your CFRelease() calls do check for NULL, but not all of them.
Most likely one of these is triggering the crash?
I'm not very familiar with ABAddressBook, so don't know in what situations they would return NULL.
On a related note, Objective-C's -release method does not crash on nil, so you may as well change: if(people) [people release]; to just [people release]; as all methods in Objective-C will silently do nothing if sent to a nil.
Related
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSContactsUsageDescription key with a string value explaining to the user how the app uses this data.
I added to the .plist NSContactsUsageDescription
doesn't work - device version:10.0
KTSContactsManager *addressBookManager = [KTSContactsManager sharedManager];
addressBookManager.delegate = self;
addressBookManager.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"firstName" ascending:YES]];
if ([isAddressBookTaken isEqualToString:#"false"]) {
[addressBookManager importContacts:^(NSArray *contacts) {
[EBLogger logWithTag:#"TBLContactManager" withBody:#"importContacts"];
DLPhoneBook *phoneBook = [DLPhoneBook new];
NSMutableArray *mutableArray = [NSMutableArray new];
for (int i = 0; i < contacts.count; ++i) {
NSDictionary *record = [contacts objectAtIndex:i];
NSError *err = nil;
DLContactRecord *contactRecord = [[DLContactRecord alloc] initWithDictionary:record error:&err];
NSLog(#" %# %# %# '",contactRecord.firstName, contactRecord.lastName, contactRecord.id);
}
}
You have to add information list in your plist,
Here is information plist for various privacy.
Add Privacy that you want in you plist and check again.
and ADD this code in your file,
- (void)viewDidLoad {
[super viewDidLoad];
contactList=[[NSMutableArray alloc] init];
ABAddressBookRef m_addressbook = ABAddressBookCreate();
if (!m_addressbook) {
NSLog(#"opening address book");
}
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(m_addressbook);
CFIndex nPeople = ABAddressBookGetPersonCount(m_addressbook);
for (int i=0;i < nPeople;i++) {
NSMutableDictionary *dOfPerson=[NSMutableDictionary dictionary];
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
//For username and surname
ABMultiValueRef phones =(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:(NSString *)ABMultiValueCopyValueAtIndex(eMail, 0) forKey:#"email"];
}
//For Phone number
NSString* mobileLabel;
for(CFIndex i = 0; i < ABMultiValueGetCount(phones); i++) {
mobileLabel = (NSString*)ABMultiValueCopyLabelAtIndex(phones, i);
if([mobileLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel])
{
[dOfPerson setObject:(NSString*)ABMultiValueCopyValueAtIndex(phones, i) forKey:#"Phone"];
}
else if ([mobileLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel])
{
[dOfPerson setObject:(NSString*)ABMultiValueCopyValueAtIndex(phones, i) forKey:#"Phone"];
break ;
}
[contactList addObject:dOfPerson];
CFRelease(ref);
CFRelease(firstName);
CFRelease(lastName);
}
NSLog(#"array is %#",contactList);
}
}
For more about it visit,
http://sugartin.info/2011/09/07/get-information-from-iphone-address-book-in-contacts/
Hope it will help you.
I am not able to retrieve mobile number from below code, i am trying lots of thing but unable to solve it. please help me
//this below code is for saving mobile number and phone number
ABRecordRef newPerson = ABPersonCreate();
ABMultiValueAddValueAndLabel(phone, (__bridge CFTypeRef)(txtMob2.text), kABHomeLabel, NULL);
ABRecordSetValue(newPerson, kABPersonPhoneProperty, phone, &error);
//image
NSData *dataref = UIImagePNGRepresentation(imgProfile.image);
ABPersonSetImageData(newPerson, (__bridge CFDataRef)(dataref), &error);
ABAddressBookAddRecord(addressbook, newPerson, &error);
ABAddressBookSave(addressbook, nil);
CFRelease(newPerson);
// Now Below code is of displaying details.
- (void)displayContacts
{
int i;
appDelegate.arr_contact = [[NSMutableArray alloc] init];
ABAddressBookRef contactBook =ABAddressBookCreateWithOptions(nil, NULL);
NSArray *allData = (__bridge_transfer NSArray *)(ABAddressBookCopyArrayOfAllPeople(contactBook));
NSUInteger contactNum = 0;
NSInteger recordId;
ABRecordRef recId;
for (i =0; i < [allData count]; i++)
{
appDelegate.dict_contact =[[NSMutableDictionary alloc] init];
ABRecordRef ref =(__bridge ABRecordRef)(allData[i]);
//mobile no and phone no
ABMultiValueRef mobNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);
CFIndex PhoneCount = ABMultiValueGetCount(mobNum);
for (int k = 0; k <PhoneCount; k++) {
strMobile = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(mobNum, k));
strPhone = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(mobNum, k));
if ([strMobile isEqualToString:(NSString *)kABPersonPhoneMobileLabel])
{
mobileno = (__bridge NSString*)ABMultiValueCopyValueAtIndex(mobNum, k);
}
else if ([strPhone isEqualToString:(NSString *)kABHomeLabel])
{
phoneno = (__bridge NSString*)ABMultiValueCopyValueAtIndex(mobNum, k);
break;
}
NSLog(#"Mobile: %# phone: %#, %#",mobileno, phoneno, strPhone);
[appDelegate.dict_contact setObject:[NSString stringWithFormat:#"%#",mobileno] forKey:#"mobno"];
[appDelegate.dict_contact setObject:[NSString stringWithFormat:#"%#",phoneno] forKey:#"phnno"];
}
//image
NSData *imgData = (__bridge NSData *)ABPersonCopyImageDataWithFormat(ref, kABPersonImageFormatThumbnail);
UIImage *image;
if (imgData)
{
image = [UIImage imageWithData:imgData];
NSLog(#"add image: %#",image);
}else
{
image = [UIImage imageNamed:#"dummy.png"];
}
[appDelegate.dict_contact setObject:image forKey:#"image"];
[appDelegate.arr_contact addObject:appDelegate.dict_contact];
}
}
Please check my edited code.
Please See this code....
-(void)GetAddressBook
{
Contacts = [[NSMutableArray alloc]init];
if (ABAddressBookCreateWithOptions) {
#try {
ABAddressBookRef addressBook = ABAddressBookCreate();
// NSArray *people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
if (!addressBook) {
NSLog(#"opening address book");
}
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSLog(#"opening address book ==%ld",nPeople);
for (int i=0;i < nPeople;i++) {
NSMutableDictionary *dOfPerson=[NSMutableDictionary dictionary];
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
NSString *Contact;
ABMultiValueRef phones =(__bridge ABMultiValueRef)((__bridge NSString*)ABRecordCopyValue(ref, kABPersonPhoneProperty));
CFStringRef firstName, lastName;
NSMutableArray *array = [[NSMutableArray alloc]init];
NSString *email;
firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
ABMultiValueRef multiValueRef = ABRecordCopyValue(ref, kABPersonEmailProperty);
array = [(__bridge NSMutableArray *)ABMultiValueCopyArrayOfAllValues(multiValueRef) mutableCopy];
email = ([array count] > 0) ? array[0] : #"";
if(firstName)
{
Contact = [NSString stringWithFormat:#"%#", firstName];
if(lastName)
Contact = [NSString stringWithFormat:#"%# %#",firstName,lastName];
}
[dOfPerson setObject:Contact forKey:#"name"];
[dOfPerson setObject:[NSString stringWithFormat:#"%d", i] forKey:#"id"];
[dOfPerson setObject:[NSString stringWithFormat:#"%#",#""] forKey:#"found"];
[dOfPerson setObject:email forKey:#"email"];
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 ;
}
}
[Contacts addObject:dOfPerson];
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
dispatch_async(dispatch_get_main_queue(), ^{
});
Here you will get Phone number, First Name, Last name and Email Id. Here Contacts is an NSMutableArray. Also view this answer for a complete set of code.
contact details from ipad using objective-c
Try This In this code I'm getting both the name and mobile number if you want the mobile number only use this kABPersonPhoneProperty:
CFErrorRef * error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
for (int i=0;i < nPeople;i++)
{
NSString* name;
NSMutableDictionary* tempContactDic = [NSMutableDictionary new];
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
CFStringRef firstName;
firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
name = (__bridge NSString *)(firstName);
[tempContactDic setValue:name forKey:#"name"];
//fetch email id
NSString *strEmail;
NSMutableString* strMobile;
ABMultiValueRef email = ABRecordCopyValue(ref, kABPersonPhoneProperty);
CFStringRef tempEmailref = ABMultiValueCopyValueAtIndex(email, 0);
strEmail = (__bridge NSString *)tempEmailref;
strEmail = [strEmail stringByReplacingOccurrencesOfString:#"-" withString:#""];
strEmail = [strEmail stringByReplacingOccurrencesOfString:#"(" withString:#""];
strEmail = [strEmail stringByReplacingOccurrencesOfString:#")" withString:#""];
strEmail = [strEmail stringByReplacingOccurrencesOfString:#" " withString:#""];
strEmail = [strEmail stringByReplacingOccurrencesOfString:#"+" withString:#""];
strMobile = [[NSMutableString alloc] initWithString:strEmail];
if ([strEmail length] == 10) {
[strMobile insertString:#"91" atIndex:0];
}
else {
}
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:strMobile];
[tempContactDic setValue:myNumber forKey:#"phone"];
[contactsArray addObject:tempContactDic];
}
/// With below two steps of code you'll get the contacts in alphabetical order
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)];
[contactsArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
I am new to iphone App Development(using iOS6) and have been facing problem with fetching the mobile Numbers from the contact List into a UITableViewController. I can get the first name and last name correctly but the phone Numbers are being returned as null. I could not understand the reason behind this.What is it that I am doing wrong? My code is as follows:
NSMutableArray *people = (__bridge_transfer NSMutableArray *) ABAddressBookCopyArrayOfAllPeople (addressBookRef);
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue((__bridge ABRecordRef)([people objectAtIndex:indexPath.row]), kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue((__bridge ABRecordRef)([people objectAtIndex:indexPath.row]), kABPersonLastNameProperty);
ABMultiValueRef phoneNumbers = ABRecordCopyValue((__bridge ABRecordRef)([people objectAtIndex:indexPath.row]),kABPersonPhoneProperty);
if (([firstName isEqualToString:#""] || [firstName isEqualToString:#"(null)"] || firstName == nil) &&
([lastName isEqualToString:#""] || [lastName isEqualToString:#"(null)"] || lastName == nil))
{
// do nothing
}
else
{
aName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
if ([firstName isEqualToString:#""] || [firstName isEqualToString:#"(null)"] || firstName == nil)
{
aName = [NSString stringWithFormat:#"%#", lastName];
}
if ([lastName isEqualToString:#""] || [lastName isEqualToString:#"(null)"] || lastName == nil)
{
aName = [NSString stringWithFormat:#"%#", firstName];
}
//[self.tableItems addObject:aName];
NSLog(#"%# added",aName);
}
//fetch multiple phone nos. and use only 0th
id person = people[indexPath.row];
ABMultiValueRef multi = ABRecordCopyValue((__bridge ABRecordRef)(person), kABPersonPhoneProperty);
NSString* phone = (__bridge NSString*)ABMultiValueCopyValueAtIndex(multi, 0);
NSLog(#"%#",phone);
[cell.detailTextLabel setText:phone];
[cell.textLabel setText:aName];
return cell;
Here this is a full working code
-(void)GetAddressBook
{
Contacts = [[NSMutableArray alloc]init];
if (ABAddressBookCreateWithOptions) {
#try {
ABAddressBookRef addressBook = ABAddressBookCreate();
// NSArray *people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
if (!addressBook) {
NSLog(#"opening address book");
}
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSLog(#"opening address book ==%ld",nPeople);
for (int i=0;i < nPeople;i++) {
NSMutableDictionary *dOfPerson=[NSMutableDictionary dictionary];
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
NSString *Contact;
ABMultiValueRef phones =(__bridge ABMultiValueRef)((__bridge NSString*)ABRecordCopyValue(ref, kABPersonPhoneProperty));
CFStringRef firstName, lastName;
NSMutableArray *array = [[NSMutableArray alloc]init];
NSString *email;
firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
ABMultiValueRef multiValueRef = ABRecordCopyValue(ref, kABPersonEmailProperty);
array = [(__bridge NSMutableArray *)ABMultiValueCopyArrayOfAllValues(multiValueRef) mutableCopy];
email = ([array count] > 0) ? array[0] : #"";
if(firstName)
{
Contact = [NSString stringWithFormat:#"%#", firstName];
if(lastName)
Contact = [NSString stringWithFormat:#"%# %#",firstName,lastName];
}
[dOfPerson setObject:Contact forKey:#"name"];
[dOfPerson setObject:[NSString stringWithFormat:#"%d", i] forKey:#"id"];
[dOfPerson setObject:[NSString stringWithFormat:#"%#",#""] forKey:#"found"];
[dOfPerson setObject:email forKey:#"email"];
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 ;
}
}
[Contacts addObject:dOfPerson];
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
dispatch_async(dispatch_get_main_queue(), ^{
});
}
The Phone numbers are to be taken like ABMultiValueRef phones =(__bridge ABMultiValueRef)((__bridge NSString*)ABRecordCopyValue(ref, kABPersonPhoneProperty));
I am new to iphone.presently i am working in project but i have struck in the middle of the project because of don't know how to access all the email id's for each contact from the iphone contactlist through coding.if anybody knows about this concept can you please help me....
this code gives u email along with their display names and contact name too
-(NSMutableArray*)getEmailAndPhoneOfPhoneContacts
{
NSLog(#"getPhoneContacts");
NSAutoreleasePool *pool= [[NSAutoreleasePool alloc] init];
NSMutableArray *tempArray=[[NSMutableArray alloc] init];
ABAddressBookRef iPhoneAddressBook=ABAddressBookCreate();
if(!iPhoneAddressBook)
{
DLog(#"unable to open addressBook");
}
//ABPerson *newPerson;
NSAutoreleasePool *innerPool=nil;
CFArrayRef allPeople=ABAddressBookCopyArrayOfAllPeople(iPhoneAddressBook);
NSMutableArray *peopleArray=[NSMutableArray arrayWithArray:(NSMutableArray*)allPeople];
BOOL shouldReleasePool=NO;
NSInteger i;
for(i=0;i<[peopleArray count];i++)
{
if((i&255)==0)
{
innerPool= [[NSAutoreleasePool alloc] init];
shouldReleasePool=YES;
}
ABRecordRef record=[peopleArray objectAtIndex:i];
Contact *objPhoneContact=[[Contact alloc] init];
objPhoneContact.contactType=STATIC_CONTACT;
CFStringRef prefixName=ABRecordCopyValue(record, kABPersonPrefixProperty);
CFStringRef firstName=ABRecordCopyValue(record, kABPersonFirstNameProperty);
CFStringRef middleName=ABRecordCopyValue(record, kABPersonMiddleNamePhoneticProperty);
CFStringRef lastName=ABRecordCopyValue(record, kABPersonLastNameProperty);
CFStringRef suffixName=ABRecordCopyValue(record, kABPersonSuffixProperty);
NSMutableString *contactname =[[NSMutableString alloc] init];
// concating all the names
if (prefixName) {
[contactname appendString:[NSString stringWithString:(NSString*)prefixName]];
CFRelease(prefixName);
}
if (firstName) {
[contactname appendString:[NSString stringWithString:(NSString*)firstName]];
CFRelease(firstName);
}
if (middleName) {
[contactname appendString:[NSString stringWithString:(NSString*)middleName]];
CFRelease(middleName);
}
if (lastName) {
[contactname appendString:[NSString stringWithString:(NSString*)lastName]];
CFRelease(lastName);
}
if (suffixName) {
[contactname appendString:[NSString stringWithString:(NSString*)suffixName]];
CFRelease(suffixName);
}
// if emty then get the organization property
if (contactname == nil || [contactname length]<1) {
CFStringRef orgName=ABRecordCopyValue(record, kABPersonOrganizationProperty);
if (orgName) {
[contactname appendString:[NSString stringWithString:(NSString*)orgName]];
CFRelease(orgName);
}
}
//if still empty then assign (no name) to it
if (contactname == nil || [contactname length]<1)
[contactname setString:#"(no name)"];
objPhoneContact.mContactName = [contactname stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[contactname release];
contactname = nil;
ABMutableMultiValueRef multi;
int multiCount=0;
multi=ABRecordCopyValue(record,kABPersonEmailProperty);
NSUInteger emailIndex_home=301;
NSUInteger emailIndex_work=321;
NSUInteger emailIndex_other=341; //~400
multiCount=ABMultiValueGetCount(multi);
if(multiCount ==0)
{
//objPhoneContact.mEmailId=#"";
}
else
{
for( int i=0; i < multiCount; i++)
{
ContactProperty* objEmailContactProperty=[[ContactProperty alloc] init];
objEmailContactProperty.mContactPropertyString=(NSString*)ABMultiValueCopyValueAtIndex(multi, i);
objEmailContactProperty.mDisplayName=(NSString*)ABMultiValueCopyLabelAtIndex(multi, i);
objEmailContactProperty.mDisplayName=[objEmailContactProperty.mDisplayName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"_$!<>"]];
if([objEmailContactProperty.mDisplayName caseInsensitiveCompare:#"home"]==NSOrderedSame)
{
objEmailContactProperty.mContactPropId=emailIndex_home;
emailIndex_home++;
}
else if([objEmailContactProperty.mDisplayName caseInsensitiveCompare:#"work"]==NSOrderedSame)
{
objEmailContactProperty.mContactPropId=emailIndex_work;
emailIndex_work++;
}
/*
else if([objEmailContactProperty.mDisplayName caseInsensitiveCompare:#"other"]==NSOrderedSame)
{
objEmailContactProperty.mContactPropId=[NSString stringWithFormat:#"%d",emailIndex_other];
emailIndex_other++;
}
*/
else
{
objEmailContactProperty.mContactPropId=emailIndex_other;
emailIndex_other++;
}
objEmailContactProperty.mContactDataType=#"Email";
[objPhoneContact.mPropertyArray addObject:objEmailContactProperty];
[objEmailContactProperty release];
}
}
if(multi)
CFRelease(multi);
[tempArray addObject:objPhoneContact];
[objPhoneContact release];
if(shouldReleasePool)
{
[innerPool drain];
shouldReleasePool=NO;
}
}
self.mPhoneContactArray=tempArray;
CFRelease(iPhoneAddressBook);
CFRelease(allPeople);
[pool drain];
return [tempArray autorelease];
}
Make sure you import these two files:
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
-(IBAction)showPeoplePickerController
{
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
[menuArray removeAllObjects];
if(menuArray ==nil)
menuArray = [[NSMutableArray alloc] init];
for (int i = 0; i < nPeople; i++)
{
NSMutableDictionary *localDic=[[NSMutableDictionary alloc]init];
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
ABRecordID recordId = ABRecordGetRecordID(ref);
[localDic setObject:[NSString stringWithFormat:#"%d",recordId] forKey:#"Record_Id"];
//get firstname
CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
[localDic setObject:[NSString stringWithFormat:#"%#",firstName] forKey:#"first_name"];
//get lastname
CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
[localDic setObject:[NSString stringWithFormat:#"%#",lastName] forKey:#"last_name"];
NSString *contactFirstLast = [NSString stringWithFormat: #"%# %#",firstName,lastName];
[localDic setObject:contactFirstLast forKey:#"FullName"];
//get EmailIds
ABMutableMultiValueRef EmailIds = ABRecordCopyValue(ref, kABPersonEmailProperty);
CFTypeRef EmailId;
NSString *EmailLabel;
for (CFIndex i = 0; i < ABMultiValueGetCount(EmailIds); i++) {
EmailLabel=[NSString stringWithFormat:#"%#",ABMultiValueCopyLabelAtIndex(EmailIds,i)];
if([EmailLabel isEqualToString:#"_$!<Home>!$_"])
{
EmailId = ABMultiValueCopyValueAtIndex(EmailIds,i);
[localDic setObject:[NSString stringWithFormat:#"%#",EmailId] forKey:#"Email_Home"];
}
else if([EmailLabel isEqualToString:#"_$!<Work>!$_"])
{
EmailId = ABMultiValueCopyValueAtIndex(EmailIds,i);
[localDic setObject:[NSString stringWithFormat:#"%#",EmailId] forKey:#"Email_Work"];
break;
}
}
[menuArray addObject:localDic];
}
NSLog(#"%#",menuArray);
}
In this way you get all EmailIds of each people.
and also add these two frameworks in your project:
AddressBook.framework
AddressBookUI.framework
I want to export IPhone's AddressBook.sqlitedb into my IPhone application.
I have searched around the net but everything seems to iterate over the "ABAddressBook"
but i want to know that is it possible to export IPhone's AddressBook.sqlitedb into my IPhone application programmatically?
Please let me know any valuable comments!!!
Thanks for your help.....
you have to fetch every single value and then insert it into your DB.
Here is the code through which i got iphone address book into my application's Db.
just call the below method where ever you want to get iphone Address Book but i'll suggest you to call this methos in delegat.m method- DidFinishLanching:
-(void)fetchRecordsFromAddressBook
{
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
//NSArray *addresses = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
//[arrayContacts removeAllObjects];
[self emptyDataContext];
for (int i = 0; i < nPeople; i++)
{
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
////////////////// get first name ///////////////////
CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
CFStringRef nickName = ABRecordCopyValue(ref, kABPersonNicknameProperty);
CFStringRef middleName = ABRecordCopyValue(ref, kABPersonMiddleNameProperty);
////////////////// get image ///////////////////
// ABMultiValueRef ContactImage = (ABMultiValueRef) ABRecordCopyValue(ref,kABPersonImageFormatThumbnail);
NSData *data=nil;
// NSLog(#"Image Testing is : %#",ref);
if(ABPersonHasImageData(ref))
{
data = [(NSData *) ABPersonCopyImageData(ref) autorelease];
if(data)
{
// NSLog(#"Im Testing is : %#",data);
//image = [[UIImage alloc] initWithData:data];
}
}
// NSLog(#"Im agte is : %#",ContactImage);
// NSLog(#" Name is : %#",firstName);
////////////////// get email ///////////////////
ABMultiValueRef emails = (ABMultiValueRef) ABRecordCopyValue(ref, kABPersonEmailProperty);
NSString *emailID=#"";
if(ABMultiValueGetCount(emails)>=1)
{
emailID = (NSString *)ABMultiValueCopyValueAtIndex(emails,0);
}
////////////////// get phone number ///////////////////
ABMultiValueRef phones = (ABMultiValueRef) ABRecordCopyValue(ref, kABPersonPhoneProperty);
NSString *phone=#"";
NSString *homeNumber = #"";
NSString *worknumber = #"";
if(ABMultiValueGetCount(phones)>=1)
{
//int ph = [ABMultiValueCopyValueAtIndex(phones, 0) intValue];
phone = (NSString *)ABMultiValueCopyValueAtIndex(phones,0);
}
// NSLog(#"%#",(NSString*)phone);
if(ABMultiValueGetCount(phones)>=2)
{
homeNumber = (NSString *)ABMultiValueCopyValueAtIndex(phones,1);
}
if(ABMultiValueGetCount(phones)>=3)
{
worknumber = (NSString *)ABMultiValueCopyValueAtIndex(phones,2);
}
NSMutableArray *arrayContacts = [[NSMutableArray alloc] init ];
///////////////////////////// insert into array ////////////////////////////
arrayContacts = [CoreDataAPIMethods getObjectsFromContext:#"AllContactData" :#"Index" :NO :self.managedObjectContext];
//////////////////////////// insert Index ///////////////////////////////
int NewEntryID;
if ([arrayContacts count] > 0)
{
AllContactData * Contacdata = [arrayContacts objectAtIndex:0];
NewEntryID = [Contacdata.Index intValue] +1;
}
else
{
NewEntryID = 1;
}
NSString *capitalisedSentence =
[(NSString *)firstName stringByReplacingCharactersInRange:NSMakeRange(0,1)
withString:[[(NSString *)firstName substringToIndex:1] capitalizedString]];
AllContactData *Contactitem=(AllContactData *)[NSEntityDescription insertNewObjectForEntityForName:#"AllContactData" inManagedObjectContext:self.managedObjectContext];
// NSLog(#"%#",capitalisedSentence);
Contactitem.Name = capitalisedSentence;
Contactitem.LastName = (NSString*)lastName;
Contactitem.NickName = (NSString*)nickName;
Contactitem.MiddleName = (NSString*)middleName;
Contactitem.Email=(NSString*)emailID;
phone = [phone stringByReplacingOccurrencesOfString:#"(" withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#")" withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#"+" withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#" " withString:#""];
phone = [phone stringByReplacingOccurrencesOfString:#"-" withString:#""];
NSLog(#"The Replacing Stinr is : %#", phone);
Contactitem.PhoneNumber=(NSString*)phone;
Contactitem.HomeNumber=(NSString*)homeNumber;
Contactitem.WorkNumber=(NSString*)worknumber;
Contactitem.Index = [NSNumber numberWithInt:NewEntryID];
Contactitem.Image = data;
// NSLog(#"Image in databse is : %#",(NSData *)ContactImage);
if(firstName!=nil)
{
CFRelease(firstName);
}
CFRelease(ref);
}
CFRelease(allPeople);
///////////////////////////// save entries ////////////////////////////
NSError *error;
if (![managedObjectContext save:&error]) {
// Handle the error...
}
}
-(void)emptyDataContext
{
self.managedObjectContext = [(Dial_Up_AppAppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext];
NSLog(#"managedObjectContext=%#",self.managedObjectContext);
// Get all counties, It's the top level object and the reference cascade deletion downward
NSMutableArray* mutableFetchResults = [CoreDataAPIMethods getObjectsFromContext:#"AllContactData" :#"Name" :YES :self.managedObjectContext];
// Delete all Counties
for (int i = 0; i < [mutableFetchResults count]; i++) {
[managedObjectContext deleteObject:[mutableFetchResults objectAtIndex:i]];
}
//[mutableFetchResults release];
// Update the data model effectivly removing the objects we removed above.
NSError *error;
if([mutableFetchResults count] > 0)
{
if (![managedObjectContext save:&error]) {
// Handle the error.
//NSLog([error domain]);
}
}
}
Hope this will help you.