Public viewModel issues


I have a question about implementation of BindableType protocol.
In book, it looks like this:

protocol BindableType {
  associatedtype ViewModelType

  var viewModel: ViewModelType! { get set }

  func bindViewModel()

So, ViewController which conforms to this protocol will have public var viewModel: TasksViewModel! property.
I’m not sure if it is a good solution to make public var as a viewModel.

Why is viewModel binding made like this and not with UIViewController’s custom init method with viewModel as a parameter, for example?
Is it the best possible approach to bind viewModel with UIViewController for MVVM architecture in Swift?

@fpillet Can you please help with this when you get a chance? Thank you - much appreciated! :]

I agree that this is not an ideal solution, as I don’t like force-unwrapping types. This is however what I found to work best in all situations, including when you reanimate view controllers from a storyboard (in this case you don’t have access to the constructor).

This is not cast in stone! You may want to implement a different version of the protocol if you always call the UIViewController initializer. In this case you could pass the VM to the init method.

Feel free to use this chapter more as a guide on techniques, and adapt it to suit your needs.

Hope this helps,

Hi @fpillet,

Can you explain why there must be a force-unwrapping for this associatedtype viewModel?
I tried to remove it, then I got: Compile error from “Scene+ViewController extension” as below:

Cannot convert value of type ‘TasksViewModel’ to expected argument type ‘TasksViewController.ViewModelType’

Additionally, in that file, if I changed “var” to “let” in below codes, the compiler also complained, “Argument passed to call that takes no arguments”. (I am guessing it’s related to “bindViewModel(to:)” is “mutating”, but I don’t know why)

let vc = nc.viewControllers.first as! TasksViewController
vc.bindViewModel(to: viewModel)
return vc

These two questions are killing me, I googled a lot and even re-read swift official docs but couldn’t find the answer. Could you please give me some idea?

Thank you in advance! Much appreciated.


I finally figured out the first question myself.

That ! in the protocol is due to “TaskViewControler” and “EditTaskViewController” also define the viewModel as a var !. That’s a “have-to-do” as there are no inits there.

But I am still confusing the second question. Why must be a var to call bindViewMode(to:)?


Oh, I figured out the second question as well. :slight_smile:

As (self.)viewModel is mutated in bindViewModel(to:), so self (a ViewController) must be a var.

Sorry about the noise, I just got confused by compiler’s confusing error messages which didn’t lead me to the right path.:frowning:

This topic was automatically closed after 166 days. New replies are no longer allowed.