iPhone SDK Accessing Address book company contact - iphone

I have been able to use the SDK to access Address Book contacts for people, but whenever I pick a contact who is a company, my app crashes.
does anyone know the property for the company field?
does anyone know the code to make it work?
thanks in advance

It seems your issue is not related to company tag itself. AB fields need to be managed carefully, released when not used and checked for nil all the time, many fields are not set.
In principle, here is example of how I use it. This function loads contacts (those fields interested for my app) and returns array with contacts to the caller. Hope this is helpful. Note how I release not needed refs.
- (NSArray *)loadContacts
{
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSMutableArray *contacts = [NSMutableArray array];
for (int i = 0 ; i < nPeople ; i++ ) {
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
NSString *firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *fullName;
if (firstName && lastName) {
fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
} else {
if (firstName) {
fullName = [NSString stringWithString:firstName];
} else if (lastName) {
fullName = [NSString stringWithString:lastName];
} else {
continue;
}
}
NSString *email = nil;
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
if (emails) {
NSArray *emailAddresses = [(NSArray *)ABMultiValueCopyArrayOfAllValues(emails) autorelease];
if (emailAddresses && [emailAddresses count] > 0)
email = [emailAddresses objectAtIndex:0];
CFRelease(emails);
}
if (email) {
NSDictionary *contact = [NSDictionary
dictionaryWithObjectsAndKeys:fullName, #"name",
email, #"email", nil];
[contacts addObject:contact];
}
if (firstName)
CFRelease(firstName);
if (lastName)
CFRelease(lastName);
}
CFRelease(allPeople);
CFRelease(addressBook);
return contacts;
}

you need to use kABPersonOrganizationProperty property for get the company name from addressbook

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..

How to access contacts only with email address in address book?

I am accessing all of the users contacts and emailing them through the app. I can access all of the contacts fine, if they have an email address. If they don't have an email address, then it gives me an error, I am trying to check if they have an email address before I attempt to add the address to the list of addresses. I am using this code. It gives me an error on the line of the if statement here: if ((ABMultiValueCopyValueAtIndex(email, 0) != NULL))
How can I access only the contacts who have email addresses?
NSMutableArray* contactsArray = [NSMutableArray new];
ABAddressBookRef m_addressbook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(m_addressbook);
CFIndex nPeople = ABAddressBookGetPersonCount(m_addressbook);
for (int i=0;i < nPeople;i++)
{
NSMutableDictionary* tempContactDic = [NSMutableDictionary new];
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
CFStringRef firstName, lastName;
firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
NSString *name = [NSString stringWithFormat:#"%# %#", firstName, lastName];
[tempContactDic setValue:name forKey:#"name"];
//fetch email id
NSString *strEmail;
ABMultiValueRef email = ABRecordCopyValue(ref, kABPersonEmailProperty);
if ((ABMultiValueCopyValueAtIndex(email, 0) != NULL))
{
CFStringRef tempEmailref = ABMultiValueCopyValueAtIndex(email, 0);
strEmail = (__bridge NSString *)tempEmailref;
[contactsArray addObject:strEmail];
}
}
The error is because you are trying to check whether there are email address available by copying the first item in the array and check if the value is NULL. But if the array is empty you can't copy any items from it.
What you should do is check if the array holds any items:
if (ABMultiValueGetCount(email) > 0) {
// There is at least one item in the email array/
}
Also be aware they your code only copies the first e-mail address for the contact, if more then 1 e-mail is set for that contact you might want to loop thru the e-mail array.
U can use this code to fetch all emails of all users from your contacts.
- (void) getEmailsOfAllContacts
{
ABAddressBookRef _addressBookRef = ABAddressBookCreate();
NSArray * allPeople = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(_addressBookRef);
for (id record in allPeople)
{
CFTypeRef emailProperty = ABRecordCopyValue((__bridge ABRecordRef)record, kABPersonEmailProperty);
NSArray * allEmailArray = ((__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty));
NSString * email;
for (int i = 0; i < [allEmailArray count]; i++)
{
email = [allEmailArray objectAtIndex: i];
if (isEmpty(email) == NO)
{
[_allContactsEmailArray addObject: email];
}
}
}
CFRelease(_addressBookRef);
allPeople = nil;
}

Optimize Objective C code to access contacts

I have some code to copy contacts from Addreesbook. It works perfectly if there is a small number of contacts. Now In my phone there us 1200 contacts and the app crashes when I tried to copy them. Can anyone help me to optimize this code or rewrite code? The code I am using is added below:
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSString *requestContactsString = #"<contacts>";
for (int i=0; i<nPeople; i++)
{
NSLog(#"Started : %d", i);
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
CFTypeRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
CFTypeRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
CFTypeRef email = ABRecordCopyValue(ref, kABPersonEmailProperty);
CFTypeRef phone = ABRecordCopyValue(ref, kABPersonPhoneProperty);
requestContactsString = [requestContactsString stringByAppendingFormat:#"<item>"];
if(firstName)
{
requestContactsString = [requestContactsString stringByAppendingFormat:#"<firstname>%#</firstname>", firstName];
CFRelease(firstName);
firstName = nil;
}
if(lastName)
{
requestContactsString = [requestContactsString stringByAppendingFormat:#"<lastname>%#</lastname>", lastName];
CFRelease(lastName);
lastName = nil;
}
if(email)
{
if(ABMultiValueGetCount(email)>0)
{
CFTypeRef em = ABMultiValueCopyValueAtIndex(email, 0);
requestContactsString = [requestContactsString stringByAppendingFormat:#"<email>%#</email>", em];
CFRelease(em);
}
CFRelease(email);
email = nil;
}
if(phone)
{
if(ABMultiValueGetCount(phone)>0)
{
CFTypeRef ph = ABMultiValueCopyValueAtIndex(phone, 0);
requestContactsString = [requestContactsString stringByAppendingFormat:#"<phone>%#</phone>", ph];
CFRelease(ph);
}
CFRelease(phone);
phone = nil;
}
requestContactsString = [requestContactsString stringByAppendingFormat:#"</item>"];
}
if(allPeople)
{
CFRelease(allPeople);
allPeople = nil;
}
if(addressBook)
{
CFRelease(addressBook);
addressBook = nil;
}
requestContactsString = [requestContactsString stringByAppendingFormat:#"</contacts>"];
NSString *hashedContactsString = [self generateHashedPassword:requestContactsString];
The major inefficiency I can see is the use of [NSString stringByAppendingFormat] which is creating a new NSString object each time it's called. This means that you have a large number of long auto-released NSString objects that are no longer being used until the next run loop (unless you are using ARC, in which case the situation is probably better).
I think you would make much better use of memory, and get better performance, by making requestContactsString an NSMutableString and using [NSMutableString appendString] (reference) instead. This would modify the existing object, allocating more memory to accept the new string.
Each append would look like this:
[requestContactsString appendString:[NSString stringWithFormat:#"<lastname>%#</lastname>", lastName]];
Which still creates a large number of auto-released objects, but they are much smaller.
Use a NSMutableString and build your XML with the appendFormat: method. In your loop you are copying the whole string you've assembled so far multiple times.

app crashes when using kABPersinPhoneProperty

I am trying to get all the phone number from the Phone Book of iPhone. But my app crashes as soon as I try to fetch the number using kABPersonPhoneProperty. The code snippet is here
ABAddressBookRef addressBook = ABAddressBookCreate();
NSMutableArray *allPeople = (NSMutableArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
int nPeople = ABAddressBookGetPersonCount(addressBook);
CFRelease(addressBook);
for(int i=0; i < nPeople; i++ ){
ABRecordRef person = [allPeople objectAtIndex:i];
NSString *name = #"";
CFTypeRef fName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFTypeRef lName = ABRecordCopyValue(person, kABPersonLastNameProperty);
ABMultiValueRef multi = ABRecordCopyValue(person , kABPersonPhoneProperty);
NSString *number = (NSString *)ABMultiValueCopyValueAtIndex(multi, 0);
if ([number length] > 0) {
if(fName != NULL)
{
if (lName != NULL) {
name = [[NSString stringWithFormat:#"%#", fName] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
else {
name = [[NSString stringWithFormat:#"%#", fName] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
NSLog(#"Number==>%# ",number);
}
}
if (fName != NULL) {
CFRelease(fName);
}
if (lName != NULL) {
CFRelease(lName);
}
if (multi != NULL) {
CFRelease(multi);
}
}
[allPeople release];
I am unable to figure out the error in this. I am also releasing everything even then it is not running smoothly.
I am even getting potential memory leak when running build and analyze for the code part
ABMultiValueRef multi = ABRecordCopyValue(person , kABPersonPhoneProperty);
NSLog(#"Number===>%d" , ABMultiValueGetCount(multi));
Please help me out to come.
Any kind of help would be highly appreciated.
Thanks in advance
Thanks for the response. I have figured out the solution fot the problem here. I did not release number variable thinking that the reference was passed as reference but it is copied to the returned location, hence need to release number after the usage.
thanks again for all the responses!!

Getting iPhone addressbook contents without GUI

I would like to list all phone numbers (or any other field) of people in the addressbook.
I've written the following code:
- (void)addressBookFill{
ABAddressBookRef addressBook = ABAddressBookCreate();
people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
[addressBook release];
}
- (void)printAddressBook{
for(id person in people){
NSLog(#"%#", [person class]);
NSLog(#"\t%#", person );
}
}
When I invoke the printAddressBook method I get this on my console:
2010-07-06 10:34:11.998 app[91420:207] __NSCFType
2010-07-06 10:34:11.999 app[91420:207] <CPRecord: 0x5d56ce0 ABPerson>
And I don't have any idea, how to dereference this ABPerson object, how to get any info from it.
I tried:
firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
but I got some exceptions.
Can anybody tell me how to get some info from these objects?
Read the documentation about the ABPerson class:
http://developer.apple.com/mac/library/documentation/UserExperience/Reference/AddressBook/Classes/ABPerson_Class/Reference/Reference.html
and also the ABRecord class:
http://developer.apple.com/mac/library/documentation/UserExperience/Reference/AddressBook/Classes/ABRecord_Class/Reference/Reference.html#//apple_ref/occ/cl/ABRecord
[ person valueForProperty: #"propName" ]
You can get the available properties with:
[ ABPerson properties ]
[ EDIT ]
On iPhone, you can use the following code to access a value:
NSString * lastName = (NSString *)ABRecordCopyValue( person, kABPersonLastNameProperty );
May be this code will help you for iOS5, please like it
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *arrayOfAllPeople = (__bridge_transfer NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger peopleCounter = 0;
for (peopleCounter = 0;peopleCounter < [arrayOfAllPeople count]; peopleCounter++){
ABRecordRef thisPerson = (__bridge ABRecordRef) [arrayOfAllPeople objectAtIndex:peopleCounter];
NSString *name = (__bridge_transfer NSString *) ABRecordCopyCompositeName(thisPerson);
NSLog(#"First Name = %#", name);
ABMultiValueRef emails = ABRecordCopyValue(thisPerson, kABPersonEmailProperty);
for (NSUInteger emailCounter = 0; emailCounter < ABMultiValueGetCount(emails); emailCounter++){
/* And then get the email address itself */
NSString *email = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(emails, emailCounter);
NSLog(#"Email : %#",email);
}
}
CFRelease(addressBook);
You want get only those contact who has email on my contact so use this code for iOS5
Please like it if it work
First add AddressBook.framework and #import <AddressBook/AddressBook.h>
- (NSArray*)printAddressBook{
NSMutableArray *mutableData = [NSMutableArray new];
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *arrayOfAllPeople = (__bridge_transfer NSArray *) ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger peopleCounter = 0;
for (peopleCounter = 0;peopleCounter < [arrayOfAllPeople count]; peopleCounter++){
ABRecordRef thisPerson = (__bridge ABRecordRef) [arrayOfAllPeople objectAtIndex:peopleCounter];
NSString *name = (__bridge_transfer NSString *) ABRecordCopyCompositeName(thisPerson);
NSLog(#"First Name = %#", name);
ABMultiValueRef emails = ABRecordCopyValue(thisPerson, kABPersonEmailProperty);
for (NSUInteger emailCounter = 0; emailCounter < ABMultiValueGetCount(emails); emailCounter++){
/* And then get the email address itself */
NSString *email = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(emails, emailCounter);
NSLog(#"Email : %#",email);
NSMutableDictionary *personDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:name,#"name",email,#"email", nil];
[mutableData addObject:personDict];
}
}
CFRelease(addressBook);
return [NSArray arrayWithArray:mutableData];
}