具有核心数据问题的搜索栏

Searchbar with core data issues

我有一个搜索 bar.And 数据显示在带有滚动视图的标签中。

例如:

核心数据字段:

1.id
2.company
3.Employe姓名

4.Address

如果我在搜索栏中键入 ID、公司或员工姓名,我想显示相关结果。

我的代码:

对于搜索数据:

  func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {

       var request = NSFetchRequest(entityName: "Agency")
     request.returnsObjectsAsFaults = false
      var   countResult : NSArray   = context.executeFetchRequest(request, error: nil)!



    let result  = NSPredicate(format: "SELF CONTAINS[c] %@",searchText)


    self.filtered = self.countResult.filteredArrayUsingPredicate(result!)



    if (filtered.count == 0 ) {
        searchActive = false;
    }else {
        searchActive = true;
    }

   println(filtered)

}

它显示错误“'不能对集合使用 in/contains 运算符”。

这些代码无法满足我的要求 want.And 我也不知道如何根据搜索栏中的输入值获取相关行。

提前致谢。

第一个问题是您的谓词 - 您试图在 NSManagedObject 子类上使用 CONTAINS,但 CONTAINS 仅适用于 String。要检查您的搜索文本是否包含在您的任何托管对象中,您需要评估它是否包含在每个属性中(在您的情况下 idcompanyempolyeeName,我是假设他们都是 Strings)。

为此,您应该将谓词更改为:

let searchPredicate = NSPredicate(format: "id BEGINSWITH %@ OR
                                           company BEGINSWITH %@ OR
                                           employeeName BEGINSWITH %@", 
                                           searchText, searchText, searchText)

我建议使用 BEGINSWITH 而不是 CONTAINS[c],因为在搜索时您的用户很可能会输入短语的第一部分。此外,正如 Apple 在其 2013 年 WWDC 演讲中所说 核心数据性能优化和调试 -

...we've got begins with and ends with and that's by far the cheapest query that you can execute.

...

Contains is more expensive because we have to work along and see whether it contains...

并且在搜索的情况下,您希望搜索速度快!

其次,在从 CoreData 取回结果后您不需要过滤结果。您可以在 NSFetchRequest 上设置 predicate 属性,您返回的结果将被过滤。例如:

let request = NSFetchRequest(entityName: "Agency")
request.predicate = // Your predicate...

let results = context.executeFetchRequest(request, error)
// Now do what you need with the results.

最后一点,最好不要从 executeRequest 中强制展开结果,以防出现问题并返回 nil - 在这种情况下,您的应用程序会崩溃。您可以改为使用:

if let unwrappedResults = results {
    // Now do what you want with the unwrapped results.
}

我怀疑这与你在谓词格式中使用SELF有关,错误消息中提到的"collection"是你的控制器sub/class代码驻留。

尝试这样的事情(请原谅我是 Obj-C 不是 Swift 所以可能语法不正确)。

let searchAttribute = <<entity.attribute key path>>
let result = NSPredicate(format:"%K CONTAINS[cd] %@",searchAttribute, searchText)

其中 %K 指的是关键路径,在 Core Data 的情况下是您的实体属性。例如:Agency.name 如果您的 Agency 对象存在该属性。

了解 Predicate Format String Syntax


第三条评论后更新...

在我的应用程序中,我的解决方案包括在生成的 NSManagedObject subclass 核心数据的扩展中创建自定义方法。如果这听起来像你明白我的意思,请告诉我,我会 post 详细信息。

与此同时,在任何 class 你的 UISearchBar 被控制的情况下创建一个自定义方法...(抱歉 Obj-C 而不是 Swift)

- (NSString *)searchKey {
    NSString *tempSearchKey = nil;

    NSString *searchAtrribute1 = Agency.attribute1;
    NSString *searchAtrribute2 = Agency.attribute2;
    NSString *searchAtrribute3 = Agency.attribute3;
    NSString *searchAtrribute4 = Agency.attribute4;

    tempSearchKey = [NSString stringWithFormat:@"%@ %@ %@ %@", searchAtrribute1, searchAtrribute2, searchAtrribute3, searchAtrribute4];

    return tempSearchKey;
}

你显然需要一个强引用让你的 Agency 实体对象在 class 中持久化,否则你需要将这段代码嵌入到你的 searchBar 函数中.

工作还好吗?