objective-c - 通讯录联系人排序

标签 objective-c ios

我在下面有这段代码,我设法从地址簿中获取列出的姓名和电话号码,但如何按名字对它进行排序?

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>"
)

最佳答案

您可以使用以下方法按名称对条目进行排序:

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);
}

前者看起来更干净,但只是另一种选择,以防你想在 ARC 世界中避免 CFRelease

顺便说一下,在 iOS 6 中使用 ABAddressBookRequestAccessWithCompletion 检查以确保您有权访问地址簿(使用条件检查以确保它仍然适用于早期版本的 iOS)。即使您使用的是早期版本的 iOS,您也应该手动询问用户是否有权限。

关于objective-c - 通讯录联系人排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13976555/

相关文章:

ios - 横向的 UIPrintInteractionController

ios - 如何在 WKWebView 中加载带有参数的 POST URLRequest?

ios - 如何播放 MPMediaItemCollection?

ios - 尝试仅在启用位置服务时运行代码导致无限循环

ios - 不断调用方法,直到 View 被取消

objective-c - NSTask 字符输出到 NSTextField 无缓冲作为连续流

ios - 设置按钮的标签值以在单元格单击时取消隐藏

ios - 在 UIScrollView 末尾加载更多数据

iphone - UIToolbar渐变修复

iphone - Facebook 应用程序中的 titleView 图标(像那样绘制的算法?)