How to Use a @Fetchrequest with the New Searchable Modifier in Swiftui

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

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

SwiftUI View and @FetchRequest predicate with variable that can change

had the same problem, and a comment of Brad Dillon showed the solution:

var predicate:String
var wordsRequest : FetchRequest<Word>
var words : FetchedResults<Word>{wordsRequest.wrappedValue}

init(predicate:String){
self.predicate = predicate
self.wordsRequest = FetchRequest(entity: Word.entity(), sortDescriptors: [], predicate:
NSPredicate(format: "%K == %@", #keyPath(Word.character),predicate))

}

in this example, you can modify the predicate in the initializer.

Input a dynamic value into @FetchRequest, to fetch a single entity from core data in SwiftUI

@FetchRequest is dynamic property which is initialised, as any other property, before your AccountMainPage init is called, so self is not available yet, that is why you cannot use title property which is a member of self, and that is about what compiler error tells.

So here is a possible solution: we initialise fetch request property with stub request and then in init, which is called later, reinitialise it with real fetch request.

Here is an approach demo (all unrelated things cut):

struct ContentView: View {
var title: String

@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: Accounts.fetchRequest()) var fetchedAccount: FetchedResults<Accounts>

init(title: String) {
self.title = title
_fetchedAccount = FetchRequest<Accounts>(fetchRequest: Accounts.getSpecificAccounts(findTitle: title))
}

...


Related Topics



Leave a reply



Submit