1

Below is what I am using to retrieve the contacts list from the device. I want it to be displayed alphabetically but using other examples seen on stack overflow I have been unable to get it to work. The code below is from a tutorial, what do I need to do to it to sort according to alphabetical order?

- (void)getPersonOutOfAddressBook
{
    //1
    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

if (addressBook != nil) {
    NSLog(@"Succesful.");

    //2
    NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);

    //3
    NSUInteger i = 0; for (i = 0; i < [allContacts count]; i++)
    {
        Person *person = [[Person alloc] init];
        ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
        //4
        NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson,
                                                                              kABPersonFirstNameProperty);
        NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
        NSString *fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];

        person.firstName = firstName; person.lastName = lastName;
        person.fullName = fullName;

        //email
        //5
        ABMultiValueRef emails = ABRecordCopyValue(contactPerson, kABPersonEmailProperty);

        //6
        NSUInteger j = 0;
        for (j = 0; j < ABMultiValueGetCount(emails); j++) {
            NSString *email = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(emails, j);
            if (j == 0) {
                person.homeEmail = email;
                NSLog(@"person.homeEmail = %@ ", person.homeEmail);
            }
            else if (j==1) person.workEmail = email; 
        }

        //7 
        [self.tableData addObject:person];
    }

    //8
    CFRelease(addressBook);
} else { 
    //9
    NSLog(@"Error reading Address Book");
}
}

This is my UITableView code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}

Person *person = [self.tableData objectAtIndex:indexPath.row];
cell.textLabel.text = person.fullName;

return cell;
}

I have tried below

[self.tableData sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

I have also tried NSSortDescriptor but I don't have a Key to sort by.

Steve Wilford
  • 8,894
  • 5
  • 42
  • 66
Manesh
  • 528
  • 6
  • 20

3 Answers3

2

You'll need to sort the array of Person objects. Once you have finished adding them all to the array you can sort on the fullName using the following code:

[self.tableData sortUsingComparator:^NSComparisonResult(Person *p1, Person *p2) {
    return [p1.fullName compare:p2.fullName];
}];

Alternative

You may want to implement a compare: method on the Person object and perform the comparison there, this will keep sorting logic nicely encapsulated and ensure that anything else that uses Person objects can easily perform sorts without duplicating the code shown above.

@implementation Person

// Mostly likely this implementation will contain more code, not shown for brevity

- (NSComparisonResult)compareByFullName:(Person *)otherPerson {
    return [self.fullName compare:otherPerson.fullName];
}

@end

Then you can sort the array with:

[self.tableData sortUsingSelector:@selector(compareByFullName:)];
Steve Wilford
  • 8,894
  • 5
  • 42
  • 66
  • 1
    Great answer, although it will probably more useful to compare lastName (and possibly firstName afterwards) than fullName to get a sorting behaviour that aligns with usual expectations. – Markus Dheus Aug 19 '15 at 13:04
0

You need to implement and provide a method to sort a Person record as a selector for the sortUsingSelector method invocation.

Markus Dheus
  • 576
  • 2
  • 8
0

I managed to solve it like this.

//keys with fetching properties NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactEmailAddressesKey]; CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];

//Order contacts by Surname. request.sortOrder = CNContactSortOrderFamilyName;

--OR YOU CAN--

//Order contacts by Name. request.sortOrder = CNContactSortOrderGivenName;

Carl Du Plessis
  • 325
  • 3
  • 6