【问题标题】:Using MVVM with dependency Injection and Storyboard将 MVVM 与依赖注入和 Storyboard 结合使用
【发布时间】:2022-01-06 10:20:38
【问题描述】:

我有一个 viewController,它设计在 Storyboard 的一页中,是应用程序的初始/主屏幕。我正在尝试从 api 获取一些数据,然后在我的屏幕上更新一个 collectionView。我之前确实得到了数据,但现在我正在尝试在应用中构建一个 MVVM 结构。

我尝试将应用程序转换为 MVVM 的方式基本上是;构建一个 ViewModel 并使用依赖注入使用 ViewModel初始化 ViewController。你可以看到我的依赖注入如下:

class ViewController: UIViewController {
    
//MARK: - Properties

private var viewModel: ViewControllerViewModel? = nil

//MARK: - Lifce Cycle

override func viewDidLoad() {
    super.viewDidLoad()
}
    
//    //MARK: - Init
init(with viewModel: ViewControllerViewModel) {
    self.viewModel = viewModel
    super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
  }
}

但问题是,我的 viewModel 根本没有被初始化。我确实在 ViewModel 的 init() 中设置了一些断点,但它们永远不会被击中,并且下面的 ViewModel 永远不会执行。就 MVVM 设计模式而言,我在这里缺少什么?

class ViewControllerViewModel {

init() {

   }
}

注意:我在 SceneDelegate 上调用 viewController,如下所示。如何使用以下情节提要初始化 ViewController?:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    guard let _ = (scene as? UIWindowScene) else { return }

    DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
        self?.window?.rootViewController = UIStoryboard(name: "PopularMovies", bundle: nil).instantiateInitialViewController()
        self?.window?.makeKeyAndVisible()
    }
    
}

图片:

  • 我的 viewController 上面什么都没有,是最初的 viewController,只有 1 页。只是想了解为什么在我的 ViewController 正在初始化时我的 viewModel 根本没有被初始化。

【问题讨论】:

    标签: ios json swift mvvm dependency-injection


    【解决方案1】:

    使用 Storyboard 时,将调用 coder init。基本上你永远不会调用你的 init。

    你可以在创建 viewController 时传递虚拟机

    let viewController = // init the VC
    viewController.viewModel = viewModel // create the VM you want to pass here.
    

    【讨论】:

    • 嗨。我已经编辑了问题的一部分。可以看看吗?
    • 在 SceneDelegate 中也是如此。你创建一个变量 let viewController = UIStoryboard(name: "PopularMovies", bundle: nil).instantiateInitialViewController() 然后 viewController.viewModel = viewModel 你可以在这里创建然后 self?.window?.rootViewController = viewController self?.window? .makeKeyAndVisible() 有意义吗?
    • 我明白了。但是这样做我并没有用 ViewModel 初始化 ViewController。我只是在更改 ViewModel 属性的值,对吗?
    • 嗯,是的,你不能真正初始化它,因为你正在使用一个故事板,所以唯一的方法就是像这样传递它,它应该和你使用你的 init 一样工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 1970-01-01
    相关资源
    最近更新 更多