使用NSFetchResult控制器进行搜索

时间:2017-04-15 23:19:32

标签: ios search core-data swift3 nsfetchedresultscontroller

我一直在研究如何使用NSFetchResultController进行搜索,但我发现的大多数帖子都来自2年前。好吧,我试图过滤对象,在我的例子中是口袋妖怪。这是我使用的功能。

func attemptPokemonFetch(generation: String = "1", name: String = "") {
    let context = coreData.persistentContainer.viewContext

    let request: NSFetchRequest<Pokemon> = Pokemon.fetchRequest()
    let sortByName = NSSortDescriptor(key: "id", ascending: true)
    request.sortDescriptors = [sortByName]
    request.predicate = NSPredicate(format: "generation = %@", generation)
    if !name.isEmpty {
        request.predicate = NSPredicate(format: "name CONTAINS[cd] %@", name)
    }

     let controller = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
    controller.delegate = self
    self.controller = controller

    do {
        try controller.performFetch()
    }
    catch let err {
        print(err)
    }
}

我在视图中调用此函数加载,搜索栏确实更改了文本以及当段更改索引值时。我知道如何过滤口袋妖怪并使用搜索。然而,我遇到的问题是当我开始搜索时。当在特定世代中搜索神奇宝贝时,也将出现来自另一代的其他神奇宝贝。因此,我将在第2代口袋妖怪的索引2处,并且在搜索时,将出现来自不同世代的其他口袋妖怪。我不确定它是如何初始化上下文的。这就是我的搜索栏功能的样子。

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchBar == pokemonSearchBar {
        let text = pokemonSearchBar.text!
        self.attemptPokemonFetch(name: text)
        collectionView.reloadData()
    }
}

另一个例子:假设我有3种类型的人,有些是瘦的,正常的和胖的。当我在瘦人的索引时,我只想搜索那些瘦弱的人而不是所有的人。那么我需要做些什么才能实现这种行为。

非常感谢任何帮助。 :)

1 个答案:

答案 0 :(得分:1)

在您的代码中

request.predicate = NSPredicate(format: "generation = %@", generation)
if !name.isEmpty {
    request.predicate = NSPredicate(format: "name CONTAINS[cd] %@", name)
}

第二个分配替换先前分配的谓词。 您可能想要的是

if name.isEmpty {
    request.predicate = NSPredicate(format: "generation = %@", generation)
} else {
    request.predicate = NSPredicate(format: "generation = %@ AND name CONTAINS[cd] %@", generation, name)
}

更灵活的方法是使用NSCompoundPredicate

var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "generation = %@", generation))
if !name.isEmpty {
    predicates.append(NSPredicate(format: "name CONTAINS[cd] %@", name))
}
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)