[ViewModel] 类型的值没有成员 nsPredicate

Value of type [ViewModel] has no member nsPredicate

我有一个存储在 Core Data 中的书签列表,我想搜索这些书签。但是我在下面 'var query' 中的 vm.myBookmarks.nsPredicate = NSPredicate(value: true) 旁边收到这个错误。

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

private func fetchAll() {
    do {
        try fetchedResultsController.performFetch()
        guard let myBookmarks = fetchedResultsController.fetchedObjects else {
            return
        }
        self.myBookmarks = 

myBookmarks.map(MyBookmarkViewModel.init)
            
        } catch {
            print(error)
        }
    }
    
}

extension MyBookmarksViewModel: NSFetchedResultsControllerDelegate {
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        guard let myBookmarks = controller.fetchedObjects as? [MyBookmark] else {
            return
        }
        self.myBookmarks = myBookmarks.map(MyBookmarkViewModel.init)
    }
}

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 ?? ""
    }
}

我的书签

@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 {

}

这是一个 macOS 应用程序。

nsPredicate 属于 @FetchRequest 属性 包装器。但是你正在使用 NSFetchedResultsController.

制作 NSFetchedResultsController public

public let fetchedResultsController: NSFetchedResultsController<MyBookmark>

并将谓词分配给控制器

...
if newValue.isEmpty {
    vm.fetchedResultsController.fetchRequest.predicate = NSPredicate(value: true)
} else {
    vm.fetchedResultsController.fetchRequest.predicate = NSPredicate(format: "name CONTAINS[cd] %@", newValue)
}

或更短

vm.fetchedResultsController.fetchRequest.predicate = newValue.isEmpty 
    ? nil 
    : NSPredicate(format: "name CONTAINS[cd] %@", newValue)

如果你不想让控制器public在视图模型中使用辅助函数。