0

i am developing a appllication for getting contacts list .For that purpose i need get all the contact data and it should be displayed in the tableview.By referreing quick contact example provided by apple i am able to get the data.

But my question is i need to edit the contact tableview b keeping checkmark to select and insert that contact to sqlite database .Is there any solution for editing contact table view that is coming from the address framework.

Please help thanks in advance

1 Answers1

1

If the question is whether you can add a checkbox to the table view provided by AddressBookUI framework (such as the ABPeoplePickerNavigationController), no, you cannot. There are some modest UI modifications that are permissible (in iOS 8, for example, you can control which contacts are enabled and which are not), but adding your own checkbox to the cell is not possible.

You would probably best abandon AddressBookUI framework altogether, and use the AddressBook framework to programmatically retrieve the contacts from the address book, at which point you can create your own UI and do whatever you choose (e.g. add a checkmark). It's more work than the AddressBookUI interface, but you have complete control over the UX.


For example, if you want to retrieve an array of all of the contacts, you can do something like:

- (void)loadContacts {
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();

    if (status != kABAuthorizationStatusAuthorized && status != kABAuthorizationStatusNotDetermined) {
        // user previously denied permission; tell user that they have to authorize this in Settings app
        return;
    }

    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
    if (!addressBook) {
        NSLog(@"ABAddressBookCreateWithOptions failed: %@", CFBridgingRelease(error));
        return;
    }

    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
        if (!granted) {
            // tell user that they just denied permission and that they have authorize app if they want this functionality
            // note, because this block is called on background queue, don't forget to dispatch any UI update to the main queue
        } else {
            NSArray *array = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, NULL, kABPersonSortByLastName));

            dispatch_async(dispatch_get_main_queue(), ^{
                // update your model and UI here, e.g.

                self.allContacts = array;
                [self.tableView reloadData];
            });
        }

        CFRelease(addressBook);
    });
}

And your UITableViewDataSource could access these ABRecordRef properties like so:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    ContactTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    ABRecordRef person = (__bridge ABRecordRef)self.allContacts[indexPath.row];

    NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
    NSString *lastName  = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
    NSString *company   = CFBridgingRelease(ABRecordCopyValue(person, kABPersonOrganizationProperty));
    ABRecordID recordID = ABRecordGetRecordID(person);

    cell.nameLabel.text = [NSString stringWithFormat:@"%@, %@", lastName, firstName];
    cell.companyLabel.text = company;
    cell.selectedSwitch.on = [self.selectedContacts[@(recordID)] boolValue];

    return cell;
}

// this is called when user flips `UISwitch` on the `UITableViewCell`

- (IBAction)didValueChange:(UISwitch *)selectedSwitch
{
    ContactTableViewCell *cell = (id)selectedSwitch.superview.superview;        // I assume switch is in content view of cell
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];            // figure out which row that cell is
    ABRecordRef person = (__bridge ABRecordRef)self.allContacts[indexPath.row]; // get ABRecordRef for that row of model array
    ABRecordID recordID = ABRecordGetRecordID(person);                          // now get ABRecordID for that row

    BOOL oldValue = [self.selectedContacts[@(recordID)] boolValue];             // get the value of the BOOL
    self.selectedContacts[@(recordID)] = @(!oldValue);                          // flip it
}

Above, I'm assuming you have two model objects, one which is an array of the contacts, another is a dictionary of which contacts are "selected", keyed by a NSNumber representation of the ABRecordID.

Clearly, you can implement this however you want, but I just wanted to illustrate the idea.

Rob
  • 415,655
  • 72
  • 787
  • 1,044