ios - 如何将模型数据从 ViewController 传递到 ViewModel

标签 ios swift mvvm viewmodel codable

我正在修改我的应用程序以实现 MVVM 模式。

简介:

我使用 WebServices 来获取我的所有数据。

在应用程序启动时,在加载屏幕期间,我向所有 Web 服务发出请求,以便我的所有数据都可用。

例如,当我点击应用程序中的菜单以访问特定场景时,我已经拥有所有需要的数据,并且我将模型传递给带有 Segue 的相应 ViewController。

问题:

真正的问题是,将此模型数据传递到我的 ViewModel 的好方法是什么?

在请求 Web 服务和解析 json 数据后,我正在使用一个实现 Codable 协议(protocol)的结构来获取我的模型。

这是我的 ViewController 的样子:

class VigilanceViewController: UIViewController {

    @IBOutlet var outletTableView: UITableView!

    var vigilance: Vigilance?

    fileprivate let viewModel = VigilanceViewModel()

    override func viewDidLoad() {

        super.viewDidLoad()

        if let vigilance = vigilance {
            // pass data to the viewModel
        }

        outletTableView.dataSource = viewModel
    }
}

在 ViewModel 中,我不知道如何声明 Vigilance 模型或如何正确初始化 ViewModel。

这是 View 模型:

class VigilanceViewModel: NSObject {

    var items = [VigilanceViewModelItem]()
    var maxVigilance: Int = 0
    var vigilance: Vigilance? = nil

    override init() {
        super.init()

        // Append objects in my items array from the vigilance Model so that the dataSource is ready to go and clean

    }
}

extension VigilanceViewModel: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return maxVigilance - 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items[section].rowCount
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = UITableViewCell()

        // TODO

        return cell
    }
}

因为我的模型包含很多我目前在这个 ViewController 中不需要的信息,所以我正在制作一个项目数组,以便它更容易在我的 DataSource 中使用。

这是我的警戒模型的样子:

struct Vigilance: Codable {

    let result: Result

    struct Result: Codable {
        let startDate: Int
        let endDate: Int
        let sendDate: Int
        let advice: String?
        let comment: String?
        let colorMax: Int
        let details: [VigilanceDetails]?

        struct VigilanceDetails: Codable {
            let dptNumber: String
            let dptName: String
            let color: String
            let risks: [Risks]?

            struct Risks: Codable {
                let code: String
                let label: String
            }
        }
    }
}

我的第一个猜测是为什么我不能在没有可选的情况下声明我的模型是因为我没有正确的自定义初始化程序?

但这不是这里的主要问题。

我想知道如何将此模型数据(之前在此 VC 中从 prepareForSegue 获得)传递给 ViewModel,并正确初始化 ViewModel。

如果有人能在这里指导我,我将不胜感激。

我正在探索操作系统和设计模式的一些晦涩部分,尽我最大的努力去理解和应用我所学的东西。

最佳答案

My first guess on why I can't declare my model without optional is because I don't have custom initializer right ?

只要您使用 segues 启动您的 UIViewControllers,您就不能使用自定义初始化器,您可以在其中传递所需的对象。 如果你想避免可选变量,我建议写一个初始化函数,像这样(并将你的 VC 移动到 xib 文件):

class ViewController: UIViewController {
    let param: String

    init(param: String) {
        self.param = param
        super.init(nibName: "YourViewControllerNibsName", bundle: Bundle.main)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

The real question is, what is a good way to pass this model data to my ViewModel?

一旦你从代码而不是 segues 启动你的 View Controller ,你可以写一些辅助函数,通常我把它放在一个 Router (或者你喜欢的名字)类中,比如:

class AppRouter {
    // Return UIViewController not to expose the type of ViewController
    static func getViewController(with param: String) -> UIViewController {
        return ViewController(param: param)
    }
}

// Using it from an another VC
let actualVC: UIViewController!
let vcToPresent = AppRouter.getViewController(with: "yourParam")
actualVC.present(vcToPresent, animated: true, completion: nil)

关于ios - 如何将模型数据从 ViewController 传递到 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51382837/

相关文章:

iphone - 核心运动陀螺仪360度值

iphone - 实现 UIViewController 类别

ios - 我们对 Touch ID For iOS 有任何值(value)吗?

swift - 在swift中分离一个字符串

ios - 如何将数据库存储在服务器中以便在 iOS 上访问?

ios - 应用程序如何将存储的通知显示为本地化字符串?

ios - 使用错误的 Localized.string

mvvm - 如何在ReactiveUI for iOS中绑定(bind)按钮点击命令

wpf - 使用Reactiveui订购可观察的集合

c# - 绑定(bind)到属性并传递自定义 StringFormat