使用 NSFetchResult 控制器搜索
Searching with NSFetchResult Controller
我一直在研究如何使用 NSFetchResultController 进行搜索,但我遇到的大多数 post 都是 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 种类型的人,一些是瘦的、正常的和胖的。当我在瘦人索引中时,我只想搜索瘦人而不是所有人。那么我需要做什么才能实现这种行为。
非常感谢任何帮助。 :)
在您的代码中
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)
我一直在研究如何使用 NSFetchResultController 进行搜索,但我遇到的大多数 post 都是 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 种类型的人,一些是瘦的、正常的和胖的。当我在瘦人索引中时,我只想搜索瘦人而不是所有人。那么我需要做什么才能实现这种行为。
非常感谢任何帮助。 :)
在您的代码中
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)