如何在iOS 7.1中对联系人进行排序

时间:2014-03-17 20:34:00

标签: ios 64-bit abaddressbook ios7.1

在最后一次更新Xcode 5.1之后,Apple用于排序地址簿的示例代码停止工作。网址:https://developer.apple.com/library/ios/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/DirectInteraction.html

示例代码

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


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

CFRelease(addressBook);
CFRelease(people);
CFRelease(peopleMutable);

但现在,此代码会发出警告

Cast to 'void *' from smaller integer type 'ABPersonSortOrdering' (aka 'unsigned int')

在这一行

(void*) ABPersonGetSortOrdering())

我该如何修改此代码?

我实际上看了苹果的论坛,谷歌搜索它,Stackoverflowed它,还没有欢乐。

希望你能帮助我。

更新

使用64位接缝与此警告有关。它与我新推出的iPhone 5s相吻合。

2 个答案:

答案 0 :(得分:20)

正如您所说,问题在于新的64位架构。 (void*)是32位体系结构的32位指针,但是64位体系结构的64位指针。函数ABPersonGetSortOrdering()返回类型ABPersonCompositeNameFormat的值,该值在ABPerson.h中指定为uint32_t。因此,警告让您知道64位指针指向32位数字。

可以通过将返回值强制转换为unsigned long来消除警告。这是完美的,因为它在64位架构上是64位,在32位架构上是32位。

(void *)(unsigned long)ABPersonGetSortOrdering()

希望这有帮助!

答案 1 :(得分:0)

我怀疑你的问题与64位和32位架构之间的差异有关,Xcode 5.1默认启用64位支持。如果指针是64位且ints是32位,则int太小而不能保存指针值。

您可以转到目标>为您的应用停用64位编辑功能。建立设置,但我强烈建议你不要这样做。此外,以下代码适用于我,它还实现了新的创建方法,并正确实现了授权检查(这确保用户已授予您的应用程序访问联系人的权限)

CFErrorRef * err;

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, err);

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {

    if (!granted) {
        // No Access to address book, user has denied
        return;
    }

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


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

    CFRelease(addressBook);
    CFRelease(people);
    CFRelease(peopleMutable);

});

虽然如果我想要非常挑剔,我会说你应该把people数组投射到像这样的NSArray中:

NSArray *people = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);

然后考虑使用NSSortDescriptors实现排序方法,因为它们可能更快,当然也是更现代的做事方式。