Ios 如何将数据从ViewModel图层传递到View图层

Ios 如何将数据从ViewModel图层传递到View图层,ios,swift,Ios,Swift,我不知道如何将数据从我的viewModel传递到我的视图,并最终在视图中显示数据,我的视图模型类是: class主视图模型{ let sessionController:sessionController 弱var mainViewCoordinator:mainViewCoordinator? 公共var fakeUsers:[用户]? init(sessionController:sessionController=sessionController()){ self.sessionCont

我不知道如何将数据从我的viewModel传递到我的视图,并最终在视图中显示数据,我的视图模型类是:

class主视图模型{
let sessionController:sessionController
弱var mainViewCoordinator:mainViewCoordinator?
公共var fakeUsers:[用户]?
init(sessionController:sessionController=sessionController()){
self.sessionController=sessionController
}
func viewDidLoad(){
Service.instance.execute(资源:User.fake){(结果)在
打印(“\n结果\(结果)\n”)
self.fakeUsers=result.value
}
}
}
我使用的是Unbox Swift JSON解码器,打印的结果是用户对象和数组,如下所示:

([
用户(id:“5851ac2615801e2348e4ea07”,
出生日期:“2016-09-17T07:22:09.985Z”,
msisdn:“912065 979”,
电子邮件:“罗莎_bravo@yahoo.com", 
profileImageUrl:“https://s3.amazonaws.com/...", 
报告点:41607,
创建:“2016-12-14T20:31:34.185Z”,
显示名称:“Victoria Escobedo”),
用户(id:“5851ac2615801e2348e4ea09”,
出生日期:“2016-05-06T11:38:23.678Z”,
msisdn:“958842030”,
电子邮件:“方济各_barrios@gmail.com", 
profileImageUrl:“https://s3.amazonaws.com/...", 
报告点:71408,
创建:“2016-12-14T20:31:34.198Z”,
显示名称:“Gonzalo Rascón”),
用户(id:“5851ac2615801e2348e4ea08”,
出生日期:“2016-05-29T18:12:32.423Z”,
msisdn:“905534639”,
电子邮件:“ral0@gmail.com", 
profileImageUrl:“https://s3.amazonaws.com/...", 
报告点:24164,
创建:“2016-12-14T20:31:34.195Z”,
显示名称:“Ramiro Dueñas”),
...
])
我想将结果传递给视图层(MainViewController),以便在表视图单元格中显示每个用户:

类MainViewController:UIViewController、UITableViewDataSource{

@IBOutlet var tableview:UITableView!
var viewModel: MainViewModel = MainViewModel()

override func viewDidLoad() {
    super.viewDidLoad()
    viewModel.viewDidLoad()
    self.tableview?.reloadData()
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Action", style: .plain, target: self, action: #selector(action))
}

func action() {
    viewModel.userDidSelectItem(identifier: "xxxx")
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return viewModel.fakeUsers?.count ?? 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "fakeUserObjectCell") as! MainTableViewCell
    cell.fakeUserObject = viewModel.fakeUsers?[(indexPath as NSIndexPath).row]
    return cell
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "detailSegue" {
        let detailMainViewController = segue.destination as! DetailMainViewController
        if let indexPath = tableview.indexPath(for: sender as! MainTableViewCell) {
            detailMainViewController.id = viewModel.fakeUsers?[(indexPath as NSIndexPath).row].id
        }
    }
}
}

我知道我必须实现self.tableview?.reloadData()来显示伪造用户,但我不知道如何传递数据并最终显示它。

  • MainViewModel
  • MainViewModel
    viewDidLoad()中更新
    fakeUsers
  • MainViewController
  • MainViewController
    中的
    numberOfRowsInSection
    现在返回
    MainViewModel
    设置的
    fakeUsers
    计数,如下所示:

类似地,对于
cellForRowAt indepath:

编辑:

Service.instance.execute
API调用不会立即返回,但是当它返回时,数据数组应该用新内容更新&请求刷新的表
但现在的问题是,我们无法在
MainViewModel
中访问
table

因此,当
服务
获取完成时,我们可以
MainViewController
执行
table.reloadData()

我希望您能为这一点提供代码,您需要从这里开始:

class MainViewModel {
    ...

    func viewDidLoad() {
        Service.instance.execute(resource: User.fake) { (result) in
            print("\n result \(result)\n")
            self.fakeUsers = result.value
            // Edu, the table refresh notification is to be fired from here
        }
    }
}

viewModel.viewDidLoad()
中的以下
Service.instance.execute()
是一个异步调用。它还没有完成抓取,您已经调用了
self.tableview?.reloadData()
,因此这可能导致
0

我建议将
ViewModel
viewDidLoad()
更改为完成调用

func viewDidLoad() {
    Service.instance.execute(resource: User.fake) { (result) in
        print("\n result \(result)\n")
        self.fakeUsers = result.value
    }
}
像这样:

func loadUsers(completion: () -> ()) {
    Service.instance.execute(resource: User.fake) { (result) in
        print("\n result \(result)\n")
        self.fakeUsers = result.value
        completion()
    }
}
因此,在
MainViewController
viewDidLoad
中,您可以在准备就绪时将调用更改为仅
reloadData()

override func viewDidLoad() {
    super.viewDidLoad()
    viewModel.loadUsers {
        self.tableview?.reloadData()
    }
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Action", style: .plain, target: self, action: #selector(action))
}

我刚刚编辑了代码,但是我忘记了一些东西,因为问题persist@Edu是的,我们在第一个流程中遗漏了一个组件,请检查编辑。
override func viewDidLoad() {
    super.viewDidLoad()
    viewModel.loadUsers {
        self.tableview?.reloadData()
    }
    self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Action", style: .plain, target: self, action: #selector(action))
}