3

名簿から名前と電話番号をリストアップすることができたこのコードを以下に示しますが、名前で並べ替えるにはどうすればよいですか?

ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
abContactArray = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBookRef); // get address book contact array

NSInteger totalContacts =[abContactArray count];

for(NSUInteger loop= 0 ; loop < totalContacts; loop++)
{
    ABRecordRef record = (__bridge ABRecordRef)[abContactArray objectAtIndex:loop]; // get address book record

    if(ABRecordGetRecordType(record) ==  kABPersonType) // this check execute if it is person group
    {
        //ABRecordID recordId = ABRecordGetRecordID(record); // get record id from address book record

        //NSString *recordIdString = [NSString stringWithFormat:@"%d",recordId]; // get record id string from record id
        //NSLog(@"Record: %@", recordIdString);

        NSString *firstNameString = (__bridge NSString*)ABRecordCopyValue(record,kABPersonFirstNameProperty); // fetch contact first name from address book

        NSString *lastNameString = (__bridge NSString*)ABRecordCopyValue(record,kABPersonLastNameProperty); // fetch contact last name from address book
                                                                                                            //NSString *contactEmail = (__bridge NSString*)ABRecordCopyValue(record,kABPersonEmailProperty); // fetch contact last name from address book

        NSString * fullName = [NSString stringWithFormat:@"%@ %@", firstNameString, lastNameString];

        [name addObject: fullName];

        ABMultiValueRef phoneNumberMultiValue = ABRecordCopyValue(record, kABPersonPhoneProperty);
        NSUInteger phoneNumberIndex;
        for (phoneNumberIndex = 0; phoneNumberIndex < ABMultiValueGetCount(phoneNumberMultiValue); phoneNumberIndex++) {

            CFStringRef labelStingRef = ABMultiValueCopyLabelAtIndex (phoneNumberMultiValue, phoneNumberIndex);

            //NSString *phoneLabelLocalized = (__bridge NSString*)ABAddressBookCopyLocalizedLabel(labelStingRef);

            phoneNumber  = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneNumberMultiValue, phoneNumberIndex);

            CFRelease(labelStingRef);

            //NSLog(@"Name: %@ %@: %@ | %@", firstNameString, lastNameString, phoneNumber, emailAddresses);

        }
        [phone addObject: phoneNumber];


    }
}

私はこれらのコードを入れてみました:

ABRecordRef record = (__bridge ABRecordRef)[abContactArray objectAtIndex:loop]; // get address book record

//ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(
                                                           kCFAllocatorDefault,
                                                           CFArrayGetCount(people),
                                                           people
                                                           );


CFArraySortValues(
                  peopleMutable,
                  CFRangeMake(0, CFArrayGetCount(peopleMutable)),
                  (CFComparatorFunction) ABPersonComparePeopleByName,
                  (void*) ABPersonGetSortOrdering()
                  );

//NSMutableArray *data = [(__bridge NSArray *) peopleMutable mutableCopy];
NSMutableArray* data = [NSMutableArray arrayWithArray: (__bridge NSArray*) peopleMutable];

NSLog(@"sort: %@", data);

しかし、nslogは私にこれらの出力を与えました:

sort: (
"<CPRecord: 0xaa5d250 ABPerson>",
"<CPRecord: 0xaa6e050 ABPerson>",
"<CPRecord: 0xaa3d7d0 ABPerson>",
"<CPRecord: 0xaa515d0 ABPerson>",
"<CPRecord: 0xaa43b90 ABPerson>",
"<CPRecord: 0xaa6b780 ABPerson>"
)
4

1 に答える 1

18

次のコマンドを使用して、エントリを名前で並べ替えることができます。

CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault,
                                                           CFArrayGetCount(people),
                                                           people);

CFArraySortValues(peopleMutable,
                  CFRangeMake(0, CFArrayGetCount(peopleMutable)),
                  (CFComparatorFunction) ABPersonComparePeopleByName,
                  kABPersonSortByFirstName);

// or to sort by the address book's choosen sorting technique
//
// CFArraySortValues(peopleMutable,
//                   CFRangeMake(0, CFArrayGetCount(peopleMutable)),
//                   (CFComparatorFunction) ABPersonComparePeopleByName,
//                   (void*) ABPersonGetSortOrdering());

CFRelease(people);

// If you don't want to have to go through this ABRecordCopyValue logic
// in the rest of your app, rather than iterating through doing NSLog,
// build a new array as you iterate through the records.

for (CFIndex i = 0; i < CFArrayGetCount(peopleMutable); i++)
{
    ABRecordRef record = CFArrayGetValueAtIndex(peopleMutable, i);
    NSString *firstName = CFBridgingRelease(ABRecordCopyValue(record, kABPersonFirstNameProperty));
    NSString *lastName = CFBridgingRelease(ABRecordCopyValue(record, kABPersonLastNameProperty));
    NSLog(@"person = %@, %@", lastName, firstName);
}

CFRelease(peopleMutable);

または、次の手法を使用できます。

NSArray *originalArray = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
abContactArray = [originalArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    ABRecordRef record1 = (__bridge ABRecordRef)obj1; // get address book record
    NSString *firstName1 = CFBridgingRelease(ABRecordCopyValue(record1, kABPersonFirstNameProperty));
    NSString *lastName1 = CFBridgingRelease(ABRecordCopyValue(record1, kABPersonLastNameProperty));

    ABRecordRef record2 = (__bridge ABRecordRef)obj2; // get address book record
    NSString *firstName2 = CFBridgingRelease(ABRecordCopyValue(record2, kABPersonFirstNameProperty));
    NSString *lastName2 = CFBridgingRelease(ABRecordCopyValue(record2, kABPersonLastNameProperty));

    NSComparisonResult result = [firstName1 compare:firstName2];
    if (result != NSOrderedSame)
        return result;
    else
        return [lastName1 compare:lastName2];
}];

for (id object in abContactArray)
{
    ABRecordRef record = (__bridge ABRecordRef)object; // get address book record
    NSString *firstName = CFBridgingRelease(ABRecordCopyValue(record, kABPersonFirstNameProperty));
    NSString *lastName = CFBridgingRelease(ABRecordCopyValue(record, kABPersonLastNameProperty));
    NSLog(@"person = %@, %@", lastName, firstName);
}

CFRelease前者はよりクリーンに見えますが、ARCの世界で避けたい場合に備えて、もう1つのオプションです。

ちなみに、ABAddressBookRequestAccessWithCompletioniOS 6で使用して、アドレスブックにアクセスする権限があることを確認します(以前のバージョンのiOSで引き続き機能することを確認するための条件付きチェックを使用します)。また、以前のバージョンのiOSを使用している場合でも、ユーザーに手動で許可を求める必要があります。

于 2012-12-20T19:37:54.907 に答える