Singleton Service Locator Pattern and Testing in iOS
Article Summary
Bohdan Orlov tackles one of iOS development's most controversial debates: when Singletons and Service Locators are actually useful (and when they'll wreck your test suite).
This article examines why Singletons and Service Locator patterns are often labeled anti-patterns in iOS development. Orlov provides practical guidance on using these patterns while maintaining testable code, with specific Swift implementation examples.
Key Takeaways
- Singletons are global objects that violate least privilege and make debugging difficult
- Protocol-based dependency injection makes singleton-dependent code testable
- Service Locators should live at factory level, not as implicit dependencies
- Avoiding static variables for singletons forces explicit dependency passing
Use Singletons sparingly based on domain modeling and inject Service Locators explicitly through factories to keep your iOS code testable.
About This Article
iOS developers have a hard time testing code that uses singletons like UIApplication.shared and UIDevice.current. These global objects make network requests and change state in ways that can't be controlled during unit tests.
Bohdan Orlov suggests wrapping singleton functionality behind protocols, such as ImageDownloading, and passing them in as dependencies instead of accessing static instances directly.
When you pass dependencies through factories instead of using static variables, developers get compile-time errors if dependencies change. This catches problems early and prevents hidden failures across thousands of tests.