SwiftUI Dynamic Predicate for FetchRequest

I Learn faster by Example

A View cannot change its own FetchRequest after the view has been created. What if we want to modify the query string and update the display based on user input?

This SwiftUI limitation causes a small challenge when coding search boxes and other dynamic queries. The example below shows how this can be done:

  1. A View cannot change its own FetchRequest, but it can change the FetchRequest of one of its sub-Views. Thus, use a sub-View to generate the FetchRequest:

listUsers(searchTerm: searchTerm) // FetchRequest is in this sub-view

2. In listUsers, use the searchTerm via init() to generate the FetchRequest and show the results:

struct listUsers: View {

private var fetchRequest: FetchRequest<Person>

init(searchTerm: String) {

fetchRequest = FetchRequest<Person>(entity: Person.entity(),

sortDescriptors: [],

predicate: NSPredicate(format: “(name CONTAINS[c] %@)”, searchTerm))

} // end init

var body: some View {

List(fetchedRequest.wrappedValue, id:\self) {person in

Text(person.name)

}

} // end view

} // end struct

How this works

When user types the search term into the TextField, each keystroke changes the State variable, searchTerm. Each time searchTerm is changed, the new version of searchTerm gets sent to listUsers, causing the predicate to update and the list of users to be updated.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store