CodexBloom - Programming Q&A Platform

Struggling with Dependency Injection in SwiftUI for a New MVP on iOS 17

👀 Views: 46 💬 Answers: 1 📅 Created: 2025-09-13
swift swiftui dependency-injection

I'm working on a personal project and While refactoring our application, the need for clean architecture has become paramount, especially since we want to implement dependency injection in SwiftUI. Our MVP needs to be flexible enough to allow us to swap out services easily for testing and future features. I've been trying to set up a simple environment where my ViewModels can receive their dependencies via initializers, but I keep running into issues with binding and state management. Currently, I’m employing the `@StateObject` and `@EnvironmentObject` mechanisms for state management, and I’ve implemented a basic service locator pattern as illustrated below: ```swift class ServiceLocator { static let shared = ServiceLocator() lazy var networkService: NetworkService = NetworkService() lazy var dataService: DataService = DataService(networkService: networkService) } ``` My ViewModel is structured to receive its dependencies like this: ```swift class MyViewModel: ObservableObject { private let dataService: DataService init(dataService: DataService) { self.dataService = dataService } } ``` When I try to instantiate `MyViewModel` within a SwiftUI view, I end up with a crash. Here’s how I’m trying to use it: ```swift struct ContentView: View { @StateObject private var viewModel = MyViewModel(dataService: ServiceLocator.shared.dataService) var body: some View { Text("Hello, World!") } } ``` The error message states that there is an unexpected `nil` value, which makes me think that the service locator is not being initialized correctly before being accessed. I’ve tried moving the initialization of `ServiceLocator` to different points in the app lifecycle, but nothing seems to work. I’ve also considered using a dependency injection framework like Swinject but feel hesitant since we’re still in the MVP stage and want to keep things lightweight. Any advice on how to properly set up dependency injection with SwiftUI in this context would be greatly appreciated. Is there a more efficient way to handle this, or am I just missing something in the setup?