实施类似于本机联系人搜索的搜索?

时间:2017-03-28 10:32:19

标签: ios search nspredicate

在本机联系人应用程序上,当您尝试搜索联系人时,键入一些字符串,如果联系姓名/姓氏/公司等,请以此字符串开头,将显示联系人。

为了使事情变得更复杂,你可以输入像Mi Ric这样的东西,搜索会找到Michael Richardson。 Ric Mi也会给我Michael Richardson。

我已将联系人记录的副本复制到我的本地核心数据存储中,现在我的第一直觉是使用<wd:Report_Data xmlns:wd="urn:com.workday.report/Test"> <wd:Report_Entry> <wd:Location_Changes> <wd:EmployeeID>111111</wd:EmployeeID> <wd:CountryCode>US</wd:CountryCode> <wd:RegionCode>RX</wd:RegionCode> <wd:StartDate>2013-07-01</wd:StartDate> </wd:Location_Changes> <wd:Location_Changes> <wd:EmployeeID>111111</wd:EmployeeID> <wd:CountryCode>US</wd:CountryCode> <wd:RegionCode>MD</wd:RegionCode> <wd:StartDate>2009-09-14</wd:StartDate> </wd:Location_Changes> <wd:Location_Changes> <wd:EmployeeID>111111</wd:EmployeeID> <wd:CountryCode>US</wd:CountryCode> <wd:RegionCode>MD</wd:RegionCode> <wd:StartDate>2009-10-14</wd:StartDate> </wd:Location_Changes> <wd:Location_Changes> <wd:EmployeeID>111111</wd:EmployeeID> <wd:CountryCode>US</wd:CountryCode> <wd:RegionCode>RX</wd:RegionCode> <wd:StartDate>2014-07-01</wd:StartDate> </wd:Location_Changes> </wd:Report_Entry> </wd:Report_Data> 和一些不错的谓词。

但我怎么会这个谓词呢?如果人物记录最多有3个单词,我应该用startsWith查询每个单词吗?这甚至可以用一个谓词来完成吗?

2 个答案:

答案 0 :(得分:3)

以下是我用于字基谓词的内容:

+ (NSPredicate *)wordBasedPredicateForString:(NSString *)searchString withProperty:(NSString *)property
{

   // searchString = [searchString stringForSearch];
    NSArray *searchStrings = [searchString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

    NSMutableArray<NSPredicate *> *subPredicates = [NSMutableArray array];

    for (NSString *string in searchStrings)
        if (![string isEqualToString:@""]) {
            NSString *mainString = [property stringByAppendingString:@" CONTAINS[cd] "];        
            mainString = [NSString stringWithFormat:@"%@ CONTAINS[cd] %%@",property];
            NSPredicate *predicate = [NSPredicate predicateWithFormat:mainString, string];
            [subPredicates addObject:predicate];
        }


    if ([searchString containsString:@" "] && subPredicates.count > 0) {
        NSString *mainString = [property stringByAppendingString:@" CONTAINS[cd] "];
        mainString = [mainString stringByAppendingString:@"' '"];

        NSPredicate *emptySpacePredicate = [NSPredicate predicateWithFormat:mainString, nil];

        [subPredicates addObject:emptySpacePredicate];
    }


    NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];

    return predicate;
}

假设我们有一个Contact对象,其name属性

NSPredicate *namePredicate = [self wordBasedPredicateForString:searchString withProperty: @"name"];

然后过滤数组:

NSArray *results = [contacts filteredArrayUsingPredicate:namePredicate];

当然你可以为姓名,公司,地址等制作多个单词基础谓词,并制作一个像这样的复合预测:

orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[namePredicate, addressPredicate, phonePredicate]];

希望它会有所帮助;)

答案 1 :(得分:1)

您也可以尝试此解决方案

让我们来看看MyContact class

class MyContact: NSManagedObject {

    @NSManaged var contact_id: String // Primary key
    @NSManaged var firstname: String
    @NSManaged var lastname: String

    var fullName: String {
        return firstname + " " + lastname
    }

}

现在您的对象中有fullName个字符串。所以你可以很容易地对它进行谓词。没关系,您的searchString与您的名字或姓氏相符。

现在添加搜索逻辑: -

var currentContacts : [MyContact] = []
var contacts : [MyContact] = []

使用currentContacts数组和contacts数组的tableView委托方法只保留所有联系人。

您可以根据搜索字符串过滤contacts数组。

currentContacts = contacts.filter { (element: MyContact) -> Bool in
    return element.fullName.localizedCaseInsensitiveContainsString(searchString)
}
tableView.reloadData()

希望它会有所帮助;)