0

I am trying to access ABAddressBook properties of a person based on recordID, but each time, I try to get a property, I get a null value.

This is the code I have tried.

    ABAddressBookRef addressBook = NULL;
    addressBook = ABAddressBookCreateWithOptions(addressBook, nil);
    ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, (ABRecordID) [[object valueForKey:@"recordId"] description]);
    NSString *firstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSLog(@"First Name %@", firstName);
    NSString *lastName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
    NSString *name = [NSString stringWithFormat:@"%@" "%@", lastName, firstName];
    NSLog(@"Full Name %@", name);

What am I doing wrong here?

Edit: I have kind of figured out the above problem. This is what I have used. The problem now I am having is that I need to reload my UITableView only when this block of code completes execution. But I am not able to figure out when this block completes execution. Needs help.

CFErrorRef myError = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &myError);
ABAddressBookRequestAccessWithCompletion(addressBook,
                                         ^(bool granted, CFErrorRef error) {
                                             if (granted) {

                                                 ABRecordID recID = [recordId intValue];

                                                 ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, recID);
                                                 NSString *firstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);

                                                 NSString *lastName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
                                                 if(!firstName){
                                                     firstName = @"";
                                                 }
                                                 if(!lastName){
                                                     lastName = @"";
                                                 }

                                                 NSString *name = [NSString stringWithFormat:@"%@ %@", lastName, firstName];
                                                 if([firstName length] < 1 && [lastName length] < 1){
                                                     name = @"No Name";
                                                 }
                                                 self.personName = name;
                                                 NSData  *imageData = (NSData *)CFBridgingRelease(ABPersonCopyImageData(person));
                                                 if(imageData){
                                                     self.personImage = [UIImage imageWithData:imageData];
                                                 }
                                                 else{
                                                     self.personImage = [UIImage imageNamed:@"default.png"];
                                                 }

                                                 NSMutableArray *array = [NSMutableArray array];
                                                 [array addObject:self.personName];
                                                 [array addObject:self.personImage];

                                                 [self.personDetailsArray addObject:array];
                                                 [self.tableView reloadData];

                                             } else {
                                                 // Handle the error
                                             }
                                         });

IS updating UIElements inside a block the right way to do? If not what are the alternatives.

What I would like to have is to have my UITableView loaded/updated only after the execution of the block. Couldn't find anything helpful yet

Xavi Valero
  • 2,047
  • 7
  • 42
  • 80

1 Answers1

0

I think you're creating your address book wrong. Try creating your address book with this:

 ABAddressBookRef addressBook = ABAddressBookCreate();

You don't need to declare as NULL in the first line so remove that. Then try to get the person object and see if it returns a valid reference.

Also, I believe ABAddressBookCreateWithOptions has parameters as follows:

ABAddressBookRef ABAddressBookCreateWithOptions (
   CFDictionaryRef options,
   CFErrorRef* error
);

but instead of options you're passing in a reference to an address book. I didn't have much luck with ABAddressBookCreateWithOptions so I just use ABAddressBookCreate. It's deprecated in iOS 6 but that's not a deal-breaker for me.

Jai Govindani
  • 3,181
  • 21
  • 26