Search code examples
iosobjective-cxcodeios6xcode4.5

Showing contact name and no. from address book, throwing exception NSInvalidArgumentException


I'm retrieving Contact name and phone no. from the Address book in my application. I'm printing them in log and it is working fine. But when I try to show them on the table view, I'm getting the exception NSInvalidArgumentException. I have a button on the view controller, pressing which the table view should get populated with the contact names and their no.s:

- (IBAction)syncContacts:(id)sender
{
    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
    for (int i = 0; i < ABAddressBookGetPersonCount(addressBook); i++) {
        ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);

        NSString *contact = (NSString *)CFBridgingRelease(ABRecordCopyCompositeName(ref));

       // NSString* phone = nil;

        ABMultiValueRef phoneNumbers = ABRecordCopyValue(ref,kABPersonPhoneProperty);

      //  if (ABMultiValueGetCount(phoneNumbers) > 0) {

        NSString *phone = (__bridge_transfer NSString*)
            ABMultiValueCopyValueAtIndex(phoneNumbers, 0);

      //  }
        NSDictionary *curContact=[NSDictionary dictionaryWithObjectsAndKeys:(NSString *)contact,@"Name",phone,@"phone",nil];

        [self.phoneContacts addObject:curContact];
    }

    tableView.delegate = self;
    tableView.dataSource = self;
    [tableView reloadData];


    NSLog(@"%@",self.phoneContacts);

    NSLog(@"%i",[self.phoneContacts count]);




}

And the table view methods are:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.phoneContacts count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"Cell";

    UITableViewCell *cell = [tableView   dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }

   // cell.textLabel.text = [self.phoneContacts objectAtIndex:indexPath.row];


    cell = [self.phoneContacts objectAtIndex:indexPath.row];
    return cell;


}

What's wrong with the table view? When the phoneContacts had only the name, it was working fine.([phoneContacts addObject:contact]). But now when I'm adding the dictionary object, it is throwing this exception.

I've made a change.

 cell = [[self.phoneContacts objectAtIndex:indexPath.row] objectForKey:@"AddressBook"];

The exception doesn't come now. But nothing is getting shown on screen.

Here's the edited method:

- (IBAction)syncContacts:(id)sender
{
    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
    for (int i = 0; i < ABAddressBookGetPersonCount(addressBook); i++) {
        ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
       // NSNumber *contact = (NSNumber *)ABRecordCopyComposite();// (ref));
        NSString *contact = (NSString *)CFBridgingRelease(ABRecordCopyCompositeName(ref));

       // NSString* phone = nil;

        ABMultiValueRef phoneNumbers = ABRecordCopyValue(ref,kABPersonPhoneProperty);

      //  if (ABMultiValueGetCount(phoneNumbers) > 0) {

        NSString *phone = (__bridge_transfer NSString*)
            ABMultiValueCopyValueAtIndex(phoneNumbers, 0);

      //  }
      //  NSDictionary *curContact=[NSDictionary dictionaryWithObjectsAndKeys:(NSString *)contact,@"Name",phone,@"phone",nil];

        contact = [contact stringByAppendingString:@"     "];
        contact = [contact stringByAppendingString:phone];
        [self.phoneContacts addObject:contact];
    }

    tableView.delegate = self;
    tableView.dataSource = self;
    [tableView reloadData];
}

The table view remains unchanged as given in the original post. It is now working.


Solution

  • The commented line cell.textLabel.text = [self.phoneContacts objectAtIndex:indexPath.row]; doesn't work? Can you set breakpoint and check if the cell's textlabel have the text assigned?

    Assigning the cell using cell = [[self.phoneContacts objectAtIndex:indexPath.row] objectForKey:@"AddressBook"] wouldn't work, unless you defined phoneContacts to be subclass of UITableViewCell.