在通常通过调用数据库获取来处理的 SwiftUI 中设置预览数据的最佳方法是啥?

Posted

技术标签:

【中文标题】在通常通过调用数据库获取来处理的 SwiftUI 中设置预览数据的最佳方法是啥?【英文标题】:What's the best way to set preview data in SwiftUI which is normally handled by calling a database fetch?在通常通过调用数据库获取来处理的 SwiftUI 中设置预览数据的最佳方法是什么? 【发布时间】:2021-06-29 17:41:17 【问题描述】:

我的应用在视图的 .onAppear 方法中调用了数据库,但我想使用 SwiftUI 的预览功能。有没有办法可以在预览窗口中模拟或禁用此功能?

struct MyView: View 

    @State var dataArray: [Data] = [Data]()
     
    var body: some View 
        VStack  
             ForEach(dataArray)  data in
                 Text(data.text) 
        
        .onAppear 
            getData()
        
    

    private func getData() 
        someCallToDatabase()  returnedData in
            self.dataArray = returnedData
    


struct MyView_Previews: PreviewProvider 
    
    static var previews: some View 
        MyView()        
    

基本上,我想手动传递数据而不被覆盖,或者以某种方式向我的数据库调用程序类添加一个扩展,当它知道它只是用于预览时,它会自动设置一些虚拟数据。

谢谢大家,嘎吱嘎吱!

【问题讨论】:

这是否回答了您的问题***.com/a/63388918/12299030? 【参考方案1】:

通过使用某种依赖注入,您可以确保有一个类/对象负责执行可以模拟的数据库调用。其中一个版本可能是使用@Envrionment 发送一个对象来处理数据库调用:


struct ApiData : Identifiable 
    var id = UUID()
    var text : String


protocol DatabaseManager 
    func someCallToDatabase(_ callback : ([ApiData]) -> Void)


class RealDatabaseManager : DatabaseManager 
    func someCallToDatabase(_ callback: ([ApiData]) -> Void) 
        callback([]) //do real database call here
    


class MockDatabaseManager : DatabaseManager 
    func someCallToDatabase(_ callback: ([ApiData]) -> Void) 
        callback([])
    


private struct DatabaseEnvironmentKey: EnvironmentKey 
    static let defaultValue : DatabaseManager = RealDatabaseManager()


extension EnvironmentValues 
    var databaseManager : DatabaseManager 
        get  self[DatabaseEnvironmentKey.self] 
        set  self[DatabaseEnvironmentKey.self] = newValue 
    


struct MyView: View 

    @State var dataArray: [ApiData] = [ApiData]()
    @Environment(\.databaseManager) private var databaseManager : DatabaseManager
     
    var body: some View 
        VStack 
             ForEach(dataArray)  data in
                 Text(data.text)
             
        
        .onAppear 
            getData()
        
    

    func getData() 
        databaseManager.someCallToDatabase  returnedData in
            self.dataArray = returnedData
        
    


struct MyView_Previews: PreviewProvider 
    static var previews: some View 
        MyView().environment(\.databaseManager, MockDatabaseManager())
    


当然,您需要确保在非预览视图中,您还在父视图中使用 .environment(...)real 数据库管理器向下传递到视图层次结构中,所以它会涉及对现有代码的一些轻微修改。

【讨论】:

以上是关于在通常通过调用数据库获取来处理的 SwiftUI 中设置预览数据的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:随机“调用中的额外参数”错误

SwiftUI - 我可以在按钮操作中使用完成处理程序吗?

按下按钮时 SwiftUI 2.0 iOS 14 Core 数据删除实例

SwiftUI - MVVM之ViewModel

数据更改 SwiftUI 时多次调用 Firebase 侦听器

视图模型中的 Firestore 方法未在 SwiftUI onAppear 方法中调用