使用NSFetchResult控制器进行搜索(Searching with NSFetchResult Controller)

编程入门 行业动态 更新时间:2024-10-23 10:23:19
使用NSFetchResult控制器进行搜索(Searching with NSFetchResult Controller)

我一直在寻找如何使用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种类型的人,有些是瘦的,正常的和胖的。 当我在瘦人的索引时,我只想搜索那些瘦弱的人而不是所有的人。 那么我需要做些什么才能实现这种行为。

非常感谢任何帮助。 :)

I've been looking on how to search using a NSFetchResultController but most post I came across are from 2 years ago. Okay I'm trying to filter the objects, which in my case are Pokemon. Here is my function I'm using.

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

I call this function in view did load, search bar did change text and when the segment changes index value. I know how to filter the Pokemon and use the searching. However the problem I come across is when I begin searching. When searching for a Pokemon in a specific generation other Pokemon from another generation will also appear. So I'll be at index 2 which is for generation 2 Pokemon and when searching, other Pokemon from different generation will be appearing. I'm not sure if its how I initialize the context. This is how my search bar function look like.

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

Another Example: Lets say I have 3 types of people some are skinny, normal and fat. When I'm at the index for skinny people I only want to search for people that are skinny not all the people. So what would I need to do to achieve this type of behavior.

Would really appreciate any help. :)

最满意答案

在你的代码中

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)

In your code

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

the second assignment replaces the previously assigned predicate. What you probably want is

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

A more flexible approach is to use 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)

更多推荐

本文发布于:2023-07-15 19:14:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1117725.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控制器   NSFetchResult   Controller   Searching

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!