草庐IT

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

coder 2023-09-30 原文

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

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/

有关objective-c - 通讯录联系人排序的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  3. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  4. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  5. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  6. ruby - 你会如何在 Ruby 中表达成语 "with this object, if it exists, do this"? - 2

    在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中

  7. ruby-on-rails - 在具有 ActiveRecord 条件的相关模型中按字段排序 - 2

    我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我

  8. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  9. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  10. ruby-on-rails - 在不重新查询数据库的情况下重新排序 Rails 中的事件记录? - 2

    例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果

随机推荐