Предикат @fetchRequest не обновляется при изменении значения UserDefaults SwiftUI

#swift #core-data #swiftui #nspredicate #nsfetchrequest

#быстрый #основные данные #свифтуи #нспредикат #nsfetchrequest

Вопрос:

У меня возникли проблемы с пониманием того, как заставить SwiftUI @FetchRequest использовать предикат только в том случае, если в нем хранится логическое значение UserDefaults true .

Проблема в том, что значение FetchedResults не меняется при изменении значения showAvailable . В настоящее время мне нужно перезапустить приложение, чтобы увидеть showAvailable результаты на основе значений.

 struct ContentView: View {  @AppStorage("showAvailable") private var showAvailable : Bool = false   @FetchRequest private var list: FetchedResultslt;Itemgt;    init() {  @AppStorage("showAvailable") var showAvailable : Bool = false  _list = FetchRequest(  sortDescriptors: [],  predicate: showAvailable ? NSPredicate(format: "parent == nil") : nil,  animation: .default  ) }  var body: some View {  Button("Cancel") {  showAvailable.toggle()  } }  

Ответ №1:

Я бы обновил запрос на извлечение новым предикатом в действии кнопки, и это обновление должно вызвать повторное выполнение запроса

 struct ContentView: View {  @AppStorage("showAvailable") private var showAvailable : Bool = false   @FetchRequest(sortDescriptors: [],   predicate: NSPredicate(value: true)  animation: .default)  private var list: FetchedResultslt;Itemgt;   var body: some View {  Button("Cancel") {  showAvailable.toggle()  updatePredicate()  }  .onAppear {  updatePredicate()  }  }   private func updatePredicate() {  if showAvailable {  list.nspredicate = NSPredicate(format: "parent == nil")  } else {  list.nspredicate = NSPredicate(value: true)  }   } }  

Комментарии:

1. Это отлично работает, но теперь структура инициализируется не на основе showAvailable bool. В идеале я хочу, чтобы приложение «запоминало» showAvailable значение при перезапуске. Есть идеи, как это сделать ?

2. Переместите весь if showAvaliable... раздел в отдельную функцию, а также вызовите ее из .onAppear