2

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?

SztupY
  • 10,291
  • 8
  • 64
  • 87
Dave
  • 23
  • 1
  • 3

3 Answers3

4

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);
Abizern
  • 146,289
  • 39
  • 203
  • 257
1

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

Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
dks1725
  • 1,631
  • 1
  • 20
  • 29
  • Thanks, I had this solution excluding the try, catch - what Exceptions does this typically catch? – Dave Jan 24 '11 at 13:36
  • i add try catch because without it my app crash in iPhone,not in simulator. – dks1725 Jan 25 '11 at 06:12
  • Interesting, what was the reason for the crash? Could you post the crash logs here? Also, would you be interested in testing my app to see if it crashes on your phone? Its a free app. – Dave Jan 30 '11 at 19:56
  • @Dave probably because there may not be a value for `firstName` for every contact. – Abizern Apr 13 '12 at 12:50
0

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
Jeffrey Sun
  • 7,789
  • 1
  • 24
  • 17