【问题标题】:How to re-use the same FetchRequest, rather than the same request in several views?如何在多个视图中重用同一个 FetchRequest,而不是同一个请求?
【发布时间】:2021-12-27 07:20:41
【问题描述】:

我在 ContentView 下的多个顶级视图中使用相同的获取请求。我的意思是相同的实体/谓词等。

之前我尝试在 ContentView 中执行一次请求,并将其作为数组传递给多个视图层。但是,这会阻止更改、删除等在其他视图中传播。

我只是想知道是否有另一种可行的方法?

我认为某种单例方法可能会奏效,但我担心会影响性能,但这可能比多次运行请求更重要。

另外,我想知道传递请求结果而不是数组? 然而,必须传递这个似乎很难看。

【问题讨论】:

  • 可能会在您的结构类之一中创建一个静态变量,以便您可以使用 MyClassOrStruct.sharedRequest 访问它
  • 查看架构、VIPER、MVC 等,最好是基于意见的,超出范围,也无法回答,因为我们没有太多信息
  • @PtitXav 谢谢,但这会更新吗?
  • @loremipsum 基本上该请求将被选中并添加到我的其他实体中。虽然它有一个列表和编辑屏幕。
  • 获取请求是指使用 URLSession 进行的网络调用?

标签: ios swift core-data swiftui


【解决方案1】:

您可以使用Environment 将您的模型传递给孩子,而无需将数组传递给多个视图层。您首先创建自己的EnvirnomentKey

public struct ModelEnvironmentKey: EnvironmentKey {
    public static var defaultValue: [Model] = []
}

public extension EnvironmentValues {
    var models: [Model] {
        get { self[ModelEnvironmentKey] }
        set { self[ModelEnvironmentKey] = newValue }
    }
}

public extension View {
    func setModels(_ models: [Model]) -> some View {
        environment(\.models,  models)
    }
}

我喜欢使用ViewModifiers 来设置我的环境,遵循单一职责原则:

struct ModelsLoaderViewModifier: ViewModifier {
    @FetchRequest(entity: Model(), sortDescriptors: [])
    var models: FetchedResults<Model>
    
    func body(content: Content) -> some View {
        content
            .setModels(Array(models))
    }
}

extension View {
    func loadModels() -> some View {
        modifier(ModelsLoaderViewModifier)
    }
}

然后我会在视图层次结构中非常高地添加这个修饰符。

@main
struct BudgetApp: App {
    @ObservedObject var persistenceManager = PersistenceManager(usage: .main)
    let startup = Startup()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .loadModels()
        }
    }
}

现在ContentView 可以从环境中读取:

struct ContentView: View {
    @Environment(\.models) var models
    
    var body: some View {
        List {
            ForEach(models) { model in
                Text(model.name)
            }
        }
    }
}

【讨论】:

  • 谢谢,这会在另一个子视图中显示在不同视图中所做的更新吗?
  • 是的,随着对上下文的更改,获取请求的结果将被更新,ModelsLoaderViewModifier 将被更新,它会使用模型更新环境值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-06
  • 2021-10-13
相关资源
最近更新 更多