I have a list of bookmarks stored with Core Data that i want to search through. But i'm getting this error next to vm.myBookmarks.nsPredicate = NSPredicate(value: true)
in 'var query' below.
Value of type '[MyBookmarkViewModel]' has no member 'nsPredicate'
@ObservedObject var vm : MyBookmarksViewModel
@State private var searchText = ""
ForEach(vm.myBookmarks) { myBookmark in
Text(myBookmark.name)
Text(myBookmark.url)
}
.searchable(text: query)
var query: Binding<String> {
Binding {
searchText
} set: { newValue in
searchText = newValue
if newValue.isEmpty {
vm.myBookmarks.nsPredicate = NSPredicate(value: true)
} else {
vm.myBookmarks.nsPredicate = NSPredicate(format: "name CONTAINS[cd] %@", newValue) }
}
}
MyBookmarksViewModel
class MyBookmarksViewModel: NSObject, ObservableObject {
@Published var myBookmarks = [MyBookmarkViewModel]()
private let fetchedResultsController: NSFetchedResultsController<MyBookmark>
private var context: NSManagedObjectContext
init(context: NSManagedObjectContext){
self.context = context
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: MyBookmark.all , managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
super.init()
fetchedResultsController.delegate = self
fetchAll()
}
............
MyBookmarkViewModel
struct MyBookmarkViewModel: Identifiable, Hashable{
init(myBM: MyBookmark) {
self.myBM = myBM
}
private let myBM: MyBookmark
var id: NSManagedObjectID {
myBM.objectID
}
var name: String {
myBM.name ?? ""
}
}
MyBookmark
@objc(MyBookmark)
public class MyBookmark: NSManagedObject, BaseModel {
static var all: NSFetchRequest<MyBookmark> {
let request: NSFetchRequest<MyBookmark> = MyBookmark.fetchRequest()
request.sortDescriptors = []
return request
}
}
extension MyBookmark {
@nonobjc public class func fetchRequest() -> NSFetchRequest<MyBookmark> {
return NSFetchRequest<MyBookmark>(entityName: "MyBookmark")
}
@NSManaged public var name: String?
@NSManaged public var url: String?
}
extension MyBookmark : Identifiable {
}
This is for a macOS app.
CodePudding user response:
nsPredicate
belongs to the @FetchRequest
property wrapper. But you are using NSFetchedResultsController
.
Make the NSFetchedResultsController
public
public let fetchedResultsController: NSFetchedResultsController<MyBookmark>
and assign the predicate to the controller
...
if newValue.isEmpty {
vm.fetchedResultsController.fetchRequest.predicate = NSPredicate(value: true)
} else {
vm.fetchedResultsController.fetchRequest.predicate = NSPredicate(format: "name CONTAINS[cd] %@", newValue)
}
Or shorter
vm.fetchedResultsController.fetchRequest.predicate = newValue.isEmpty
? nil
: NSPredicate(format: "name CONTAINS[cd] %@", newValue)
If you don't want to make the controller public use a helper function in the view model.