Search code examples
swiftswiftuisearchablefetchrequest

How to use a @FetchRequest with the new searchable modifier in SwiftUI?


Is it possible to use the new .searchable in combination with @FetchRequest?

I have a code like this:

struct FooListView: View {
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Foo.name, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Foo>

    @State var searchText = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    NavigationLink(destination: FooView(Foo: item)) {
                        Text(item.wrappedName)
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .searchable(text: $searchText)
            .navigationTitle("Foos")
        }
    }
}

I would like to use the searchText to filter my FetchedResults.


Solution

  • WWDC 2021 Bring Core Data Concurrency to Swift and SwiftUI has a great example of this right around minute 21:33

    https://developer.apple.com/wwdc21/10017

    struct ContentView: View {
        @FetchRequest(sortDescriptors: [SortDescriptor(\Quake.time, order: .reverse)])
        private var quakes: FetchedResults<Quake>
    
        @State private var searchText = ""
        var query: Binding<String> {
            Binding {
                searchText
            } set: { newValue in
                searchText = newValue
                quakes.nsPredicate = newValue.isEmpty
                               ? nil
                               : NSPredicate(format: "place CONTAINS %@", newValue)
            }
        }
    
        var body: some View {
            List(quakes) { quake in
                QuakeRow(quake: quake)
            }
            .searchable(text: query)
        }
    }