I have a view showing messages in a team that are filtered using @Fetchrequest with a fixed predicate \'Developers\'.
struct ChatView: View {
@FetchRequest(
May be a more general solution for dynamically filtering @FetchRequest.
1、Create custom DynamicFetchView
import CoreData
import SwiftUI
struct DynamicFetchView: View {
let fetchRequest: FetchRequest
let content: (FetchedResults) -> Content
var body: some View {
self.content(fetchRequest.wrappedValue)
}
init(predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor], @ViewBuilder content: @escaping (FetchedResults) -> Content) {
fetchRequest = FetchRequest(entity: T.entity(), sortDescriptors: sortDescriptors, predicate: predicate)
self.content = content
}
init(fetchRequest: NSFetchRequest, @ViewBuilder content: @escaping (FetchedResults) -> Content) {
self.fetchRequest = FetchRequest(fetchRequest: fetchRequest)
self.content = content
}
}
2、how to use
//our managed object
public class Event: NSManagedObject{
@NSManaged public var status: String?
@NSManaged public var createTime: Date?
... ...
}
// some view
struct DynamicFetchViewExample: View {
@State var status: String = "undo"
var body: some View {
VStack {
Button(action: {
self.status = self.status == "done" ? "undo" : "done"
}) {
Text("change status")
.padding()
}
// use like this
DynamicFetchView(predicate: NSPredicate(format: "status==%@", self.status as String), sortDescriptors: [NSSortDescriptor(key: "createTime", ascending: true)]) { (events: FetchedResults) in
// use you wanted result
// ...
HStack {
Text(String(events.count))
ForEach(events, id: \.self) { event in
Text(event.name ?? "")
}
}
}
// or this
DynamicFetchView(fetchRequest: createRequest(status: self.status)) { (events: FetchedResults) in
// use you wanted result
// ...
HStack {
Text(String(events.count))
ForEach(events, id: \.self) { event in
Text(event.name ?? "")
}
}
}
}
}
func createRequest(status: String) -> NSFetchRequest {
let request = Event.fetchRequest() as! NSFetchRequest
request.predicate = NSPredicate(format: "status==%@", status as String)
// warning: FetchRequest must have a sort descriptor
request.sortDescriptors = [NSSortDescriptor(key: "createTime", ascending: true)]
return request
}
}
In this way, you can dynamic change your NSPredicate or NSSortDescriptor.