Finally Apple (iOS 13 +) has added constructor dependency injection to Storyboards!
No excuses anymore for not using DI properly on UIViewControllers.
Let’s see a quick example.
We have an app with a simple Storyboard with two UIViewControllers.
The code for the second UIViewController is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
final class AnotherViewController: UIViewController { private let aDependency: String @IBOutlet weak var showDependencyLabel: UILabel! init?(coder: NSCoder, aDependency: String) { self.aDependency = aDependency super.init(coder: coder) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @IBAction func didTapButton(_ sender: Any) { showDependencyLabel.text = aDependency } } |
In order to pass the dependency we have to use the failable init method.
The code for the UIViewController that shows the AnotherViewController is:
1 2 3 4 5 6 7 8 9 10 11 12 |
import UIKit final class ViewController: UIViewController { @IBAction func didTapButton(_ sender: Any) { guard let anotherViewController = storyboard?.instantiateViewController(identifier: "AnotherViewController", creator: { coder in return AnotherViewController(coder: coder, aDependency: "something") }) else { fatalError("AnotherViewController failed to be initialized")} present(anotherViewController, animated: true, completion: nil) } } |
As the code shows all we need to do is to use the new method
instantiate