Effective Strategies for Organizing iOS Project Architectures
Written on
Chapter 1: Introduction to iOS Architecture
The objective of software architecture is to enhance understanding and facilitate replaceability. As Joachim Kurz aptly stated, "The Goal of Software Architecture is Understandability, Replaceability."
When diving into blogs and video tutorials on architectural patterns, the varied terminology can often lead to confusion. While the names of components may differ from one pattern to another, the core concepts generally remain consistent. To simplify these ideas, I will incorporate synonyms and explanations throughout this discussion.
It’s essential to recognize that no single solution fits every challenge. This necessity for diverse architectural patterns arises from the distinct problems each pattern aims to address. Utilizing an inappropriate approach can lead to unnecessary complications.
Section 1.1: Personal Journey as a Mobile Developer
Initially, I anticipated that my transition to mobile development would involve technical challenges heavily focused on mathematics and algorithms, drawing from my background in software engineering. However, I quickly realized that my expectations were misplaced—unless one is involved in SDK (framework, package) development directly.
In mobile app development, the pace is brisk; adaptations must occur rapidly. Often, Product Owners and Managers lack a clear vision of the end goal, providing only a general direction. Development frequently begins in R&D, Proof of Concept (PoC), or A/B testing formats, complicating the ability to forecast future developments when project milestones are consistently shifting.
Joining an existing project means acclimating to its organizational structure, including folder arrangements and architectural patterns. Developers must dissect problems into key components, approximate solutions, and concentrate on reaching viable outcomes. My intent in this article is to share effective organizational strategies for projects and my insights into architectural patterns using examples from iOS projects—principles that can also be applied to various front-end and UI-centric initiatives.
Section 1.2: Architectural Patterns Overview
When discussing project organization, the conversation often shifts to architectural patterns, with Model-View-Controller (MVC) being the most fundamental.
Rather than delving into the specifics of each MVC-like pattern, consider that if a screen bears excessive responsibility, a child view controller can be introduced. For scenarios necessitating increased separation, an MVC pattern supplemented with services may suffice. Alternatively, if a view possesses significant complexity, MVP could be effective, and this can be escalated to MVVM, VIPER, CleanSwift, among others.
In essence, all these patterns aim to redistribute responsibilities across different layers of code, which we will revisit later.
Chapter 2: Project Decomposition Strategies
When it comes to project decomposition, numerous approaches exist. Below, I outline four distinct methods, although many more are available.
- Technical Decomposition: Familiar to many, this approach groups components around a specific architectural pattern. For instance, in an MVC structure, all views—like LoginView and RegisterView—are organized within a dedicated View folder.
- Visual Decomposition: My preferred method, especially when the number of screens vastly exceeds the features. This strategy allows for integrating various architectural patterns within the same project while minimizing confusion, making it suitable for most applications.
- Domain Decomposition: This technique aligns more closely with features. If a screen encompasses numerous functionalities, it can be subdivided accordingly. For example, a single screen displaying both a graph and a list of articles could utilize different ViewControllers based on their respective models, a concept borrowed from parallel programming.
- Temporal Decomposition: This reflects a sequence of actions. For instance, in a linear onboarding framework or a tutorial pager view, this would be the appropriate choice.
New developers often overly concentrate on the technical dimension of decomposition, perhaps due to the influence of online tutorials. There is an excessive focus on technical organization rather than addressing real business needs.
Video Description: This video discusses the architecture of an iOS app and outlines best practices to follow.
Section 2.1: Layered Architecture Concept
When faced with frequent changes and brainstorming sessions with Product Owners, I recommend separating two fundamental concepts around which the app should be structured: Scene (e.g., Login Screen) and Feature (e.g., Geolocation, triggering notifications for deals when a user enters a shop within range). I also find value in creating visual graphs that map screens to their respective features.
The Layered Architecture concept, particularly a model with three plus one layers, has proven beneficial for complex applications. While more layers can be added for intricate scenarios, this structure generally suffices, reducing software complexity while enhancing code clarity.
The layers typically include:
- Application Layer: This is the entry-level of the app, containing essential elements like AppDelegate and SceneDelegate, along with configurations and constants needed throughout the application.
- Presentation Layer (UI Layer): This layer encompasses most screens, often outnumbering features. It includes a CommonUI folder for shared UI elements, extensions, and universal components, as well as individual folders for each screen.
- Business Logic Layer (Domain Layer): This crucial layer encapsulates the app's logic and business rules, defining the meaning behind the codebase.
- Data Layer (Core Layer, Data Access Layer): This layer is responsible for data retrieval from both local and remote sources, saving data after processing, and housing Models, Entities, and Data Transfer Objects (DTOs).
Video Description: This video showcases aesthetic ways to organize iPhone apps and home screens for a better user experience.
Section 2.2: CleanSwift Architecture within Layered Framework
As illustrated, certain components may straddle layers, indicating that in different patterns, elements can belong to various layers. What matters is maintaining a clear separation and a defined data flow.
When developers embark on app development, their primary focus often shifts towards speed, reuse, consistency, and maintainability, eventually evolving into compile-time optimization and runtime performance.
Regardless, these objectives lie at opposite ends of the spectrum, and the focus can only be on one or two aspects simultaneously.
As emphasized earlier, the main technical focus should be on understandability and replaceability—principles that I wholeheartedly endorse. Most applications contain a mix of complex screens and numerous simpler ones, justifying the use of varying architectural patterns for each screen.
For instance:
- Screen A (login, simple): Utilize MVC with a LoginService.
- Screen B (complex dashboard): Employ CleanSwift.
- Screen C (semi-complex): Implement MVC with child VCs.
Advantages of this Approach:
- Replaceability: Screens can be easily swapped as all components reside together.
- Ease of Onboarding: New developers can grasp the simpler parts of the project.
- Simplicity for Most Screens: MVC and some services suffice for many screens.
Disadvantages:
- Organizational Challenges: Poor organization may arise if features outnumber screens.
- SDK Development Drawbacks: This method may not be ideal for SDK development.
Section 2.3: Conclusion
Massive View Controllers should be avoided. If a screen's purpose is not clearly articulated in a simple sentence, it likely requires decomposition and refactoring. There is no one-size-fits-all architectural pattern; each is a solution to a specific issue. Continually ask whether a resolution will address a problem globally or locally.
If you've made it this far, thank you for reading! You deserve a coffee ☕️. If you found the content valuable, please share and follow. Your support means a lot to me. Feel free to reach out with suggestions or questions.