views:

228

answers:

4

Im reading the address book contacts... everything goes well until I test a contact with no First Name ( Since I can create a contact with just an email or a phone or wathever....). The code (reduced) is this:

- (NSMutableArray *) getContactsInfo {
    NSMutableArray *contactsList = [[NSMutableArray alloc] init];
    localAddressBook = ABAddressBookCreate();

    int contactsLength = (int)ABAddressBookGetPersonCount(localAddressBook);

    if (contactsLength < 1)
        return nil;

    for(int currentContact=1; currentContact < (contactsLength + 1); currentContact++) {
        ABRecordRef person = ABAddressBookGetPersonWithRecordID(localAddressBook,(ABRecordID) currentContact);

        firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        NSLog(@"%@", firstName);

        [contactsList addObject:firstName];
        CFRelease(person);
    }

    return contactsList;
}

and the output I get is this:

2010-02-15 14:16:25.616 testApp[7065:207] Contact0
2010-02-15 14:16:25.618 testApp[7065:207] Contact1
2010-02-15 14:16:25.619 testApp[7065:207] Contact2
Program received signal:  “EXC_BAD_ACCESS”.

I have 3 contacts with First and Last names And one created with just the last name, for test purposes.

It seems I can properly read any property such as email or address with arrays... but when a contact lacks First Name Property the app crashes.

A: 

To make sure, the crash is taking place within ABRecordCopyValue and not when you try to use firstName for the first time (which may be NULL?) Also, person is not NULL either, correct? (In general more code in the question along with details about which line is crashing would be helpful.)

Another thing to try would be to cast person to an ABRecord* and use [valueForProperty][1]; the two types are toll-free bridged and you might get a different result out of the latter (though I doubt it).

Update: Given the code you have posted you need to check that firstName is not NULL before trying to output it via NSLog - it is very possible ABRecordCopyValue is simply returning NULL (representing the fact there is no first name data present for that record.) You should also check for the validity of the person ref value itself - passing NULL in person to ABRecordCopyValue could be the source of additional problems.

fbrereto
I'm new to this board and the code I tryed to post looks ugly..Please have a look at this link fromPasteBin.com[until I learn how to post code =/]http://pastebin.com/ma738189
Octavio
A: 

You may want to enable NSZombies to see exactly where the EXEC_BAD_ACCESS is coming from.

jessecurry
A: 

The problem is indeed a nil first name - but not at the log statement, rather where you try to insert nil into the array. You cannot insert a nil value into an array, that causes a crash. NSLog has not flushed output to the console yet which is why you do not yet see your last log statement saying first name is nil.

Any time you get data out of the address book, check to see if the value is nil before you insert it into anything.

Kendall Helmstetter Gelner
+1  A: 

You are doing something very wrong in your code: you are assuming that the record IDs are sequential and starting at 1. This is not the case at all, you cannot rely on this.

What you should do instead is use ABAddressBookCopyArrayOfAllPeople to find all records in the Address Book and then use the Core Foundation CFArray functions to get to the individual items.

(Yes, the Address Book API in the iPhone is terrible)

St3fan