Home > Net >  How to filter core data entries the simpler way using @FetchRequest
How to filter core data entries the simpler way using @FetchRequest

Time:11-16

I have an entity called Car.

I have this @FetchRequest to list the cars.

@FetchRequest(
    sortDescriptors: [NSSortDescriptor(keyPath: \Car.name, ascending: true)],
    animation: .default)
    var dishes: FetchedResults<Car>

This works wonderfully but now I want to add a search bar to the view.

I know that @FetchRequest has this syntax

@FetchRequest(
    sortDescriptors: [NSSortDescriptor(keyPath: \Car.name, ascending: true)],
    predicate: // WTH I put here?,
    animation: .default)
    var dishes: FetchedResults<Dish>

I have tried to create a function called buildPredicate, as this:

func buildPredicate() -> NSPredicate {
    if searchText == "" {
        return NSPredicate(value: true)
    }
    
    return NSPredicate(format: "name CONTAINS[cd] %@", searchText)
}

but this will not work because to run this function I need self to be created first and while XCode is compiling the code self was not created yet.

The same is true for a computed var.

I know there is a way that you need to be a rocket scientist to use, and I have used it before, using something like this

struct FetchedObjects<T, Content>: View where T : NSManagedObject, Content : View {
    
  let content: ([T]) -> Content

  var request: FetchRequest<T>
  var results: FetchedResults<T>{ request.wrappedValue }
  
  // MARK: - Lifecycle
  
  init(
    predicate: NSPredicate = NSPredicate(value: true),
    sortDescriptors: [NSSortDescriptor] = [],
    @ViewBuilder content: @escaping ([T]) -> Content
  ) {
    self.content = content
    self.request = FetchRequest(
      entity: T.entity(),
      sortDescriptors: sortDescriptors,
      predicate: predicate
    )
  }

instead of FetchRequest but I am wondering if there is an easier way.

Is there a way to build a predicate for @FetchRequest that works?

CodePudding user response:

Use .onChange(of:) for your search text variable to build your predicate and update the fetch request

.onChange(of: searchText) { search in
    if search.isEmpty {
        dishes.predicate = NSPredicate(value: true)
    } else {
        dishes.predicate = NSPredicate(format: "name CONTAINS[cd] %@", search)
    }
}
  • Related