【问题标题】:iOS - ABAddressBook - filtering using a predicateiOS - ABAddressBook - 使用谓词过滤
【发布时间】:2012-11-30 06:12:00
【问题描述】:

我对以下代码中使用的谓词有疑问

   NSMutableArray *records = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople( addressBook );

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"record.phoneNumber contains %@",@"123"]; 


    @try {
            [records filterUsingPredicate:predicate];
    }
    @catch (NSException *exception) {
        NSLog(@"%@",exception);
    }
    @finally {
        //
    }

我得到的例外是:

[<__nscftype> valueForUndefinedKey:]:该类不符合键记录的键值编码。

我一直在努力寻找地址簿谓词的指南,但没有运气。有什么建议么?

【问题讨论】:

  • 您要过滤的对象是否有一个名为record 的属性,并且该对象(记录)是否有一个名为phoneNumber 的属性?如果不是,将抛出相同的异常。关于您对指南的要求,我发现this book 非常好。简洁明了。
  • 它们似乎是 __NSCFType 类型

标签: iphone ios abaddressbook


【解决方案1】:

您无法使用NSPredicates 过滤通讯录。此外,phoneNumber 不是ABRecordRef 的字段。用户可以有多个电话号码,因此您需要检查每个电话号码。

你会这样做:

CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);

NSMutableArray *matchingPeople = [NSMutableArray array];
for (CFIndex i = 0; i < CFArrayGetCount(people); i++) {
    ABRecordRef person = CFArrayGetValueAtIndex(people, i);
    ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
    int phoneNumbers = ABMultiValueGetCount(phones);
    if (phoneNumbers > 0) {
        for (CFIndex i = 0; i < phoneNumbers; i++) {
            NSString *phone = (NSString *)CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, i));
            if ([phone rangeOfString:@"123"].location != NSNotFound) {
                [matchingPeople addObject:person];
                break;
            }
        }
    }
    CFRelease(phones);
}
CFRelease(people);

就我个人而言,我不会将 ABRecordRefs 添加到数组中——我会创建一个值对象,其中仅包含您想要从记录中获取的字段并添加它,因此当您完成循环后,您可以确保你没有任何悬空的 CFTypes。

【讨论】:

猜你喜欢
  • 2015-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多