Completing the LeadEssentials Course with the Blue Belt
I’m happy to announce that I’ve completed the LeadEssentials course and earned the Blue Belt.
With this belt, I’ve completed all lectures of the course. Compared to the earlier belts, this one required completing two modules. These went particularly deep into areas that I see influencing how I design, structure, test, and evolve real-world Swift codebases.
Below is a summary of what the last two modules covered.
Sixth Module: Navigation and Advanced Patterns
The sixth module shifted the focus toward large-scale application structure, with navigation and composition taking center stage. A major theme throughout was how to design a navigation layer in Swift that remains clean, testable, and modular — even as an application grows and features become more independent. Rather than relying on tightly coupled navigation flows or shared global state, the course explored ways to navigate between features without breaking modular boundaries or introducing common anti-patterns.
Closely tied to navigation was the broader topic of app composition and dependency management. I revisited dependency injection from both object-oriented and functional perspectives and learned when each approach is most appropriate. The module also covered dependency rejection patterns, different dependency lifestyles such as singleton, transient, and scoped dependencies, and how these choices affect testability and long-term maintainability. A recurring theme was how to decouple feature modules without introducing duplication, supported by refactoring techniques that rely heavily on tests and compiler guarantees.
Another strong focus was reusability. This included creating generic components, structuring reusable presentation logic, and designing shared UI modules in a way that preserves modularity. Practical UI-related topics such as programmatic UI construction, scaling fonts correctly with Dynamic Type, and localized date formatting helped ground these architectural concepts in real user-facing concerns. The migration to diffable data sources was also covered, highlighting how they improve correctness and reduce complexity in list-based UIs.
Testing, performance, and observability were woven throughout the module. I learned how to write fast and reliable automated tests by controlling environmental factors like the current date, locale, calendar, and time zone. Snapshot testing was explored as a complementary technique to unit and integration tests, and the module emphasized choosing the right test type for each level of the system. Debugging memory leaks using Xcode’s Memory Graph Debugger, understanding when to use autorelease pools, and explicitly releasing autoreleased instances during tests rounded out the performance-focused topics.
Finally, the module addressed infrastructure concerns such as logging, profiling, and monitoring. Best practices for structured logging in Swift were combined with strategies for monitoring debug and release builds cleanly. On the asynchronous side, the course explored eliminating callback-heavy code by composing async operations with Combine, managing threading through schedulers, and reducing boilerplate while keeping asynchronous flows explicit and testable.
Seventh Module: Swift Concurrency
The seventh and final module focused entirely on Swift Concurrency and safe migration strategies. It began with enabling complete concurrency checking and learning how to interpret and resolve the resulting warnings and errors. A strong emphasis was placed on understanding concurrency boundaries by distinguishing between Sendable, @MainActor, and nonisolated contexts, as well as identifying unsafe concurrency behavior that the compiler cannot detect automatically.
Migration strategies played a central role throughout this module. I learned how to progressively move existing codebases from completion closures, DispatchQueues, or Combine to async/await while preserving existing behavior, cancellation semantics, and test reliability. This included using checked continuations to bridge legacy APIs, applying deprecation strategies to introduce async alternatives without breaking clients, and understanding why not every API should immediately become asynchronous.
The module also went deep into practical async/await usage. Topics included identifying which parts of the codebase should run on the main actor, replacing DispatchQueue-based synchronization with safer alternatives such as mutexes, and preparing projects for Swift 6’s stricter concurrency guarantees. More advanced scenarios, like migrating Core Data schedulers to concurrency-aware APIs and handling actor isolation across protocol boundaries, helped clarify how these concepts apply in larger, real-world applications.
Testing asynchronous code received particular attention. I learned how to write deterministic async tests by creating dedicated stubs for success and failure cases, implementing reusable and generic async loader spies, and controlling task completion and cancellation explicitly. The course also covered how to test concurrent workflows using async let, how to wait for tasks in a deterministic way using tools like Task.yield, and how to migrate integration and acceptance tests to async/await without sacrificing reliability.
The module concluded by tying concurrency back into composition. This included async injection in the composition root, migrating Combine-based compositions to async/await, defining async scheduler protocols for safe concurrent operations, and managing threading concerns explicitly at architectural boundaries.
Conclusion
Following this advanced curriculum with only a basic working knowledge of the Swift language and its core concepts was a challenge at times. I often needed longer than expected to understand the code examples and to implement them in my own course codebase. My prior experience with C# and .NET definitely helped bridge some of the gaps, but I also had to spend time looking up Swift-specific concepts and syntax.
Reaching the Blue Belt feels less like an endpoint and more like a solid foundation for future work in Swift and SwiftUI. The later modules especially helped connect many dots: navigation, composition, dependency management, testing, and concurrency. These concepts now feel like parts of a coherent system instead of isolated techniques.
More importantly, the course provided practical strategies for evolving existing codebases safely — something that matters far more in real projects than greenfield perfection — especially in the enterprise world, where most of my work happens.
My next steps will be less about collecting more belts (which the program does offer) and more about applying these patterns consistently in my own apps (primarily in my side projects) and refactors. Having this body of knowledge tied together in a structured way was absolutely worth the effort and I’m excited to see how it influences my work in the coming years.
There are still some other modules like the ‘iOS Dev Tooling’ module that I have started already and which I will complete in the coming weeks. I also plan to watch all lectures at least once again (which, funnily enough, translates into the next level of the Blue Belt) and complete my notes as long as I have access to the course (which closes this November).
Click to see the full iOS Lead Essentials curriculum
Disclaimer: This blog post was written with the help of AI, based on a bulleted summary of learning topics provided as part of the Lead Essentials program. The structured list served as the foundation for turning the content into a more readable, narrative-style post that reflects my personal learning experience. I reviewed and edited the post before publishing to ensure it meets the quality standards of this blog.
