首页 > 解决方案 > SwiftUI 在哪里加载 MVVM 中的数据

问题描述

我有一个名为的视图Requests,它有一个名为RequestViewModel. 此视图模型将模型类型作为参数Request,然后为视图提供多种方法。问题是我需要requests先从 firebase 加载这些,但我不知道在哪里。

视图模型是获取数据的好地方吗,因为我觉得它不是?对于其他视图模型,我也有类似的情况;对于前PackageViewModel和更多...

我应该在服务中将这些数据加载到其他地方,然后将其传递给这个视图模型,还是有其他方法可以做到这一点?

class RequestViewModel: ObservableObject {
    @Published var request: Request
    @Published var requests: [Request] = []

    init(request: Request) {
        self.request = request
    }

    func loadRequests() -> Void {
        network call here {
            self.requests = requests
        }
    } 
}

标签: iosswiftmvvmswiftuiswift5

解决方案


使用专用网络服务。

搜索你的感受,你知道这是真的。

问题是,它违背了你认为你知道的关于 MVVM 的一切。

大多数 MVVM 开发人员使用视图模型作为网络请求(具有副作用)、业务逻辑和视图控件的便捷包装器。

它背后的想法是重构视图绑定模型和相关的逻辑/效果。

与所有设计模式一样,一些开发人员会滥用它、扭曲它、从 java 复制和粘贴它……等等。

随着时间的推移,开发人员开始认为 ViewModel 是理所当然的,既然它是 Android 的规范,它必须在 iOS 中工作,对吧?

任何称职的开发人员在尝试将 MVVM 移植到 SwiftUI 时都会问这些问题:

  • SwiftUI 中有绑定机制吗?它是如何工作的?

  • struct Model: View {...},这是模型视图映射吗?如果是这样,我可能不需要声明单独的 ViewModel?(仅限专业人士的问题)

  • 谁符合 ObservableObject 就可以被观察到(触发视图更新),这超出了视图模型的狭义定义(视图相关的属性)。ObservableObject 可以是服务共享资源。例如; 网络服务。恭喜,你刚刚迈出了进入更大世界的第一步。

  • 为什么我要引入一个引用类型视图模型来为每个符合在围绕值类型构建的 SDK 中的 View 的值类型增加一个值类型模型视图?斯威夫特不是java吗?

现在我们有足够的设置来正确回答您的问题。

  1. 创建一个专门的网络服务,例如;

    final class Resource: ObservableObject { // don't even need inheritance, OOP isn't always the best solution in all situations 
        @Published var requests = [Requests]()
        // publish other resources
        func loadRequests() {
            /* update requests in callback */
        }
    }
    
  2. 使用它,例如;

    struct Model: View {
        @State var model = MyModel() // can be "view model", because it maps to view 
        @EnvironmentObject var res: Resource
        // or as an alternative, @ObservedObject var res = Resource()
        var body: some View {
            // access the automatic binding provided by SwiftUI, e.g.; res.requests
            // call res.loadRequests() to mutate internal state of a reference type
            // note that stateful part of the "view model" is refactored out 
            // so that `model` can be value type, yet it provides binding via @State
            // instead of ObservableObject, which has to be reference type
            // this is the brilliance of SwiftUI, it moves heaven and earth so you have 
            // the safety of immutability from value type, **unlike MVVM**
        }  
    }  
    
  3. 完毕。

  4. 为什么我们又需要 ViewModel?在评论中告诉我。


推荐阅读