In the source code from the Example App you can see how the Data Manager inside the App Dependencies struct is used through the whole hierarchy.
You define a global struct that conforms to the AppDependenciesProtocol
protocol and will hold all the necessary dependencies on your app
struct AppDependencies: AppDependenciesProtocol {
let dataManager: DataManager
init() {
self.dataManager = DataManager()
}
func start(with completion: @escaping () -> Void = {}) {
self.dataManager.start {
completion()
}
}
}
On the first Coordinator
in the hierarchy you need to initiate it, like in Example App AppCoordinator
...
override func start(with completion: @escaping () -> Void = {}) {
// Do not use the direct self.dependencies = dependencies way, because this method does additional things
self.setDependencies(dependencies: AppDependencies())
self.dependencies?.start { [weak self] in
...
}
super.start(with: completion)
}
...
and then from there on, you only need to conform to the HasDependencies
protocol on the Coordinators
that you want to have access to the dependencies. Coordinate takes care of injecting them automatically on the children Coordinators
for your convenience.
class MainCoordinator: TabBarCoordinator<MainViewController>, HasDependencies {
var dependencies: AppDependencies?
...
Use the struct you created as a dependencies holder to conform to HasDependencies
protocol, as shown in the example above. Do not use AppDependenciesProtocol
.
The inspiration for this system comes from here, where you can also read why it is a better solution for this problem.
Found errors? Think you can improve this documentation? Simply click the Edit link at the top of the page, and then the icon on Github to make your changes.