搜索栏中存在核心数据问题

时间:2015-04-09 08:59:42

标签: swift core-data uisearchbar

我有一个搜索栏。数据显示在带有scrollview的标签中。

例如:

核心数据字段:

1.id
2.company
3.员工姓名

4.Address

如果我在搜索栏中输入id,company或Employee Name,我想显示相关结果。

我的代码:

对于搜索数据:

  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)

}

它显示错误“'无法在/包含运算符的集合中使用”。

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

先谢谢。

2 个答案:

答案 0 :(得分:3)

第一个问题是您的谓词 - 您尝试在CONTAINS子类上使用NSManagedObject,但CONTAINS仅适用于String。要检查您的搜索文本是否包含在任何托管对象中,您需要评估它是否包含在每个属性中(在您的案例中为idcompanyempolyeeName,我是&#39 ; m假设他们都是String s。

要执行此操作,您应将谓词更改为:

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

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

  

...我们已经开始并以此结束,而且这是您可以执行的最便宜的查询。

     

...

     

包含更昂贵,因为我们必须一起工作并看到   它是否包含......

在搜索的情况下,你希望它快!

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

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.
}

答案 1 :(得分:1)

我怀疑它与您在谓词格式中使用SELF以及"集合"有关。错误消息中引用的是您的代码所在的控制器子/类。

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

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

其中%K指的是密钥路径,在核心数据的情况下是您的实体属性。例如:Agency.name如果您的Agency对象存在该属性。

了解Predicate Format String Syntax


第三次评论后更新......

在我的应用中,我的解决方案包括在Core Data生成的NSManagedObject子类的扩展中创建自定义方法。如果这听起来像你知道我的意思,请告诉我,我会发布细节。

与此同时,在你的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实体对象在课程中保留,否则您需要将这段代码嵌入到searchBar函数中。

工作正常吗?