【问题标题】:How do I ForEach over a One-To-Many Relationship in CoreData using SwiftUI?如何使用 SwiftUI 在 CoreData 中对一对多关系进行 ForEach?
【发布时间】:2020-07-06 17:04:04
【问题描述】:

我目前正在使用 CoreData 开发 SwiftUI 应用程序。我目前确实在 CoreData 中定义了 2 个实体。

带代码:

extension CoreDataRecipe: Identifiable {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<CoreDataRecipe> {
        return NSFetchRequest<CoreDataRecipe>(entityName: "CoreDataRecipe")
    }

    @NSManaged public var recipeName: String
    @NSManaged public var startDate: Date
    @NSManaged public var uuid: UUID
    @NSManaged public var recipeSteps: NSOrderedSet

}

带代码:

extension CoreDataRecipeStep: Identifiable {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<CoreDataRecipeStep> {
        return NSFetchRequest<CoreDataRecipeStep>(entityName: "CoreDataRecipeStep")
    }

    @NSManaged public var finishDate: Date?
    @NSManaged public var isActiveStep: Bool
    @NSManaged public var localStepType: String?
    @NSManaged public var stepDuration: Int32
    @NSManaged public var uuid: UUID?

    var stepType: RecipeStepType {
        set {localStepType = newValue.rawValue}
        get {RecipeStepType(rawValue: localStepType ?? "") ?? .Vorteig}
    }
}

我已经可以使用 ForEach 毫无问题地绕过父项。为此,我使用@ObservedObject。以 SwiftUI 方式保持绑定。

我是这样做的:

@FetchRequest(entity: CoreDataRecipe.entity(), sortDescriptors: []) var recipes: FetchedResults<CoreDataRecipe>
...
ForEach(recipes) { recipe in
    BreadListItem(recipe: recipe)
}

在 BreadListItem 内部,我正在使用 @ObservedObject,它就像一个魅力。

@ObservedObject var recipe: CoreDataRecipe

我现在想做的是按照我的食谱步骤做同样的事情。 我的假设是我可以对 NSOrderedSet 中的元素使用相同的 ForEach 来执行此操作,如下所示:

ForEach(recipe.recipeSteps ?? []) { step in
    RecipeStepEntryField(step: step)
}

这样做的问题是我不能遍历这些元素,因为 NSOrderedSet 不符合 RandomAccessCollection。当然,我可以将 NSOrderedSet 转换为数组,但这会破坏与对象的绑定,不是吗?我只是没有看到如何在保持 CoreData 完整的同时使用 @ObservedObject 实现与集合的绑定。

有人可以帮我吗?

【问题讨论】:

  • 我认为您可以将其转换为数组,然后将 ForEach 与数组一起使用。这应该有效并且不应该失去绑定。 transformableRecipeSteps 在哪里定义?到处都找不到
  • 对了,我忘记重命名了。转换后的RecipeSteps 实际上是recipeSteps。我编辑了帖子现在应该没问题。 (玩了一下,复制了错误的属性)谢谢你的回答,我会试试看,让你知道它是怎么回事。
  • 试过了。我可以让 ForEach 循环遍历项目而不会出现此解决方案的问题。但是,这会破坏与@NSManagedObject 的绑定。因此,每当我在步骤列表中添加或删除对象时,更新都不会出现在屏幕上。只有关闭屏幕并再次打开它才表明实际数据发生了变化。
  • 没关系!我刚刚修好了!现在将发布解决方案。 :) 非常感谢您的帮助!
  • Kein 问题 :) 来自德国北部的问候 :)

标签: binding swiftui observedobject


【解决方案1】:

在@davidev 的帮助下,我能够弄清楚。

解决方案是按如下方式更改 ForEach:

ForEach((recipe.recipeSteps?.array as? [CoreDataRecipeStep] ?? [])) { step in
    RecipeStepEntryField(step: (step) as? CoreDataRecipeStep ?? CoreDataRecipeStep(),
    showDetails: true)
}

仅此一项不起作用,但由于我使用的是 Xcode 14,因此我能够使用 @StateObject var recipe: CoreDataRecipe 来保持对配方对象的引用,这使我保持在循环中进行更新,但确实处理了删除正确列出配方项目(不是配方步骤)。之前这会导致崩溃,但由于 SwiftUI 中的最新添加,这现在是可能的。

"Data Essentials in SwiftUI" from the WWDC 2020 的演讲帮助很大(幸运的是几天前看过)。

祝所有尝试做同样事情的人好运。 CoreData 和 SwiftUI 确实还不是很舒服,但如果你愿意花一点时间,它已经可以工作了。 :)

【讨论】:

  • NSSet 没有 .array 函数。好像你正在使用一些你没有共享的帮助类。
  • 使用 NSOrderedSet ?
猜你喜欢
  • 2020-12-12
  • 2021-07-21
  • 2021-11-06
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多