【问题标题】:SwiftUI - how to update data with fetchRequest in initSwiftUI - 如何在 init 中使用 fetchRequest 更新数据
【发布时间】:2020-06-29 10:34:37
【问题描述】:

我正在 View 的 init() 方法中进行 CoreData 提取。我没有在 SwiftUI 中使用 FetchRequest,因为我需要一个基于参数的谓词,该参数也发送到视图。在@FetchRequest 中使用该参数将导致错误,因为该变量尚未初始化。

我在 init() 中执行 fetch Request

//FetchRequest
let fetch : NSFetchRequest<Article>
self.articleRows = [Article]()
fetch = Article.fetchRequest() as! NSFetchRequest<Article>
fetch.predicate = NSPredicate(format: "type == %d", self.type)

do {
    self.articleRows = try NSManagedObjectContext.current.fetch(fetch)
} catch
{
}

这工作正常。我在 ForEach 循环中显示我的所有数据。

ForEach(self.articleRows, id:\.self) { article in

但是,当我从上下文中删除实体时,我需要刷新视图以显示更改。在删除操作中,我切换 @State 变量以刷新视图。那行得通,但是实体仍在我的数组中。那是因为init() 没有被再次调用并且获取请求也没有再次发出。如果init() 被调用,被删除的实体将不再存在。

这里最好的方法是什么?如何重新获取我的 CoreData 实体。

我目前的解决方案:我目前在我的 Fetch 视图中使用 Binding。如果我进行更改,我会切换该绑定并重新加载我的父视图。这将导致我的子视图(获取视图)也重新加载,并再次发出获取请求。这是最好的方法吗?有没有更简单的解决方案?

【问题讨论】:

    标签: core-data swiftui


    【解决方案1】:

    所以,我找到了解决问题的方法。

    出了什么问题?

    视图没有更新,因为我没有使用 FetchRequest 属性包装器,因为我需要该 FetchRequest 中的实例变量。所以我需要在我的Init() 方法中进行获取。但我所做的是,我只是在 init() 中获取了一次我的项目,除非重新加载父级,否则不会更新。

    如何在不烦人的父更新的情况下解决它?

    我没有在init() 中只手动获取一次,而是使用了 FetchRequest 并在 init() 中对其进行了初始化,因此它仍然充当 FetchRequest 属性包装器,就像 Observable 对象一样。

    我是这样声明的:

    @FetchRequest var articleRows : FetchedResults<Article>
    

    init()里面

    //Here in my predicate I use self.type variable 
    var predicate = NSPredicate(format: "type == %d", self.type)
    
    //Intialize the FetchRequest property wrapper
    self._articleRows = FetchRequest(entity: Article.entity(), sortDescriptors: [], predicate: predicate)
    

    【讨论】:

      【解决方案2】:

      假设您已将 managedObjectContext 设置为这样;

      @Environment(\.managedObjectContext) var moc
      

      那么我相信这个解决方案可能对你有用。

      func deleteArticle(at index: IndexSet) {
          for i in index {
              // pull the article from the FetchRequest
              let article = articleRows[i]
              moc.delete(article)
          }
          // resave to CoreData
          try? moc.save()
      }
      

      在 ForEach 块的末尾调用该方法;

      .onDelete(perform: deleteArticle)
      

      也就是说,我不熟悉您执行 fetch 请求的方式,因此您需要进行一些调整。

      【讨论】:

      • 感谢您的回复。我有一个使用 @FetchRequest 和你的 onDelete 函数的列表。效果很好。但是,在我上面的例子中,它仍然没有更新。
      猜你喜欢
      • 1970-01-01
      • 2020-06-16
      • 2020-04-17
      • 2020-03-09
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多