0

I have an app that uses address book. I am trying to display sorted list of names from address book using

sortedArray = [arr_contactList sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

and then when user selects one of the contacts, its phone number is displayed.

I am able to sort iPhone address book phone numbers.

I use following to sort phone numbers:

ABRecordRef source = ABAddressBookCopyDefaultSource(ab);
NSArray *thePeople = (NSArray*)ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(ab, source, kABPersonSortByFirstName);

NSString *name;
for (id person in thePeople)
{
    name = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);

    ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);

    for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
    {  
        NSString* num = (NSString*)ABMultiValueCopyValueAtIndex(phones, j);

        CFStringRef locLabel1 = ABMultiValueCopyLabelAtIndex(phones, j);

        NSString *phoneLabel1 =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel1);

        [tempPhoneArray addObject:num];        
    }       
}

But my actual problem is, my names array has contacts that begin with special characters on top of the list, and when I select phone nos, the contact list sorted starts with alphabet A. So I am getting wrong phone numbers.

How do I match both the sorts - the name sort and numbers sort?

Vin
  • 10,517
  • 10
  • 58
  • 71
iOSDev
  • 3,617
  • 10
  • 51
  • 91

1 Answers1

1

In this example, you would be making 27 arrays, 1 for each letter, but the concept can be applied to any checking of special characters vs upper/lowercase. Hope this helps.

const int capacity = 27;    
NSMutableArray *subArrays = [NSMutableArray array];

//Prepopulate the subArray with 26 empty arrays
for(int i = 0; i < capacity; i++)
    [subArrays addObject:[NSMutableArray array]];
char currFirstLetter = 'a';

for(int i = 0; i < sortedArray.count; i++)
{
    NSString *currString = [[sortedArray objectAtIndex:i] lowercaseString];

    NSLog(@"%@", currString);
    NSLog(@"%c", [currString characterAtIndex:0]);
    NSLog(@"%c", currFirstLetter);

    if([currString characterAtIndex:0] == currFirstLetter)
    {
        //65 is the position of 'a' in the ascii table, so when we subtract 97, it correlates to 0 in our array.
        [[subArrays objectAtIndex:currFirstLetter-97] addObject:[sortedArray objectAtIndex:i]];
    }
    else if([currString characterAtIndex:0] < 65 || ([currString characterAtIndex:0] > 90 && [currString characterAtIndex:0] < 97) || [currString characterAtIndex:0] > 122)
    {
        //If it's a symbol (65-90 are uppercase, 97-122 are lowercase)
        [[subArrays objectAtIndex:26] addObject:[sortedArray objectAtIndex:i]];
        //Increment the letter we're looking for, but decrement the count to try it again with the next letter
    }
    else
    {
        currFirstLetter++;
        i--;
    }
}
mergesort
  • 672
  • 4
  • 10
  • what subarrays have? Code crashes at [subArrays objectAtIndex:26] :( – iOSDev May 30 '12 at 02:37
  • 1
    I added the code that instantiates subarrays, sorry about that. – mergesort May 30 '12 at 02:45
  • Thanks for the code. But with this code, array is sorted listing contacts starting with special characters on top. And I want special characters at the end, exactly similar to iPhone native addres book. :( How that can be achieved? – iOSDev May 30 '12 at 02:50
  • When you're doing the comparison in the for loop, the if statements are what determine what to do. So by taking a sorted array, and iterating through it you can determine whether it is a special character or not. If it is a special character, treat it differently, if not, do with it as you would a regular character. – mergesort May 30 '12 at 02:55