MVVM Dependency Injection using Storyboards
Inject those dependencies!
Dependency Injection: A technique that allows objects to receive other objects on which it depends
MVVM: An architecture pattern consisiting of Model, View and View-Model Storyboard: A visual representation of the User Interface of an Application
The Video Alternative
Sorry, this is awful. I’ve created two simple screens, neither of which display anything for the user other than a button to go onto the next screen. The first screen makes a network call but prints out the result to the console.
Simple stuff, right?
I’m going to implement MVVM as follows:
this means that we have three seperate sections — the View, View Model and Model.
This means that in this particular case I don’t have a model. Why? Because the data I’m pulling in from the network manager will be decoded without a model — not a problem as I’ll be showing how the View and ViewModel interact in this example.
In order to show how this architecture might be tested, in the test target (so adding a new swift file in your project tests) I’ve added the following
This means that when
getData() is called in the mock the closure is called, which can be tested for. Excuse the force-unwrapping as this isn't something that I'd usually do but in a test target, well, I do it.
This is then tested with the following tests:
So I’m swapping in the mock ViewModel with it’s own injected dependencies (which on another day I might check is being called correctly from the ViewModel etc). The expectation is fulfilled when the
getData() function is called. Nice! The
MockNetworkManager is included as part of my package, which works well.
In order to produce network calls I recommend using my Network Manager which can then be added to a project by clicking on the blue project name and clicking on
Swift Packages and the plus sign asd highlighted in the image below
The view controller is instantiated from the Storyboard, which will call the
required init and create the viewModel:
now if we are creating a test instance of the view controller we need another initializer:
which in itself does the same, initiating a view controller — however in this instance it is injected (and you can see how that works in the test written above).
This gives us the full
ViewController class as follows:
Here is how the initializer (and property) looks:
So the generic network manager is passed through the initializer, and
AnyNetworkManager works as a type of wrapper (which is that type erasure).
This is then used when
getData() is called - and then there is a nice little bit of code that prints out the server respose to the console.
Yes — there is a force-unwrap there but I’m not suggesting that you do that in production code, this would usually be an if-let but is here in the demo code in any case.
When you press the button you can segue to a
NextViewController. To create this view controller and view model the same applies - that is I'm using the same style of initializers as before.
Want to see the code? Here it is:
Which then allows you to create the same network calls as before
I hope this gives you the ability to make some great apps and really move on your app development.
If you’ve any questions, comments or suggestions please hit me up on Twitter