When I finally got the data saved in Core Data and showed them in a list, I was looking for a way to make the list searchable, in hope that the list would dynamically update itself when user starts searching.
In the tutorial I was following, it was introducing me to write a whole new FetchRequest filtered list, which I found to be quite difficult to follow. But I know that I can make a normal List searchable by using the .searchable()
modifier, can I use this for the fetchedResults<DataType>
?
The answer is yes, after searching for a while, I found this great answer on StackOverflow, someone has exactly the same question as I did, and the answers was working like a charm.
The answer is here:
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)
}
}
The only thing we need to update here is the “place” in NSPredictate(format: “place CONTAINS %@”)
And if you have more than one predicate for your search, you can use the NSCompoundPredicate() like this, as provided in another answer on StackOverflow
let p1 = NSPredicate(format: "username = %@", "user")
let p2 = NSPredicate(format: "password = %@", "password")
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [p1, p2])
You can choose to use the logic operator and, or, not, in the NSCompoundPredicate, it is “and” in the example above.
Top comments (0)