How to structure your files with VIPER Architecture
Tags: architecture, mobile, viper, development
Published: 2024-07-16 23:39:48

Maybe you already had the theory of how VIPER Architecture work but that's only the THEORY, in the real work can be painful implement a Software Architecture because you can have a lot of cases that you can't know how to implement correctly accordly VIPER Architecture (But this can happen when whatever Architecture). 

I'll explain you how to implement correctly VIPER with a common cases, but if you have an especific scenario you can comment to discuss how VIPER can solvent correctly.

## PhonebookApp (iOS)
A classic one. Let's supouse that you need to do a simple Phonebok application where stores contact.

```python
PhonebookApp # Root directory of the application

├── Common # Shared code between features
│   ├── Models # Data models representing entities
│       ├── Contact.swift # Represents a single contact with its information
│       └── ContactGroup.swift # Represents a group of contacts
│   ├── Utils # Utility classes for common functionalities
│       ├── NetworkManager.swift # Handles communication with network services
│       └── StorageManager.swift # Handles data persistence and retrieval
│   └── ViewModels # View models for data presentation
│       ├── ContactDetailViewModel.swift # Prepares data for the contact detail view
│       ├── ContactGroupListViewModel.swift # Prepares data for the contact group list view
│       └── ContactListViewModel.swift # Prepares data for the contact list view
├── Features # Individual features of the application # Feature for managing a single contact
    ├── ContactDetail
        ├── Views # UI components for displaying the contact
        │   └── ContactDetailView.swift # Xcode Storyboard or SwiftUI view for contact details
        ├── Interactors # Business logic for contact data
        │   └── ContactDetailInteractor.swift # Fetches, updates, and deletes contact data
        ├── Presenters # Prepares data for the contact detail view
        │   └── ContactDetailPresenter.swift # Receives data from interactor and formats it for view
        └── Routers # Navigation logic for the contact detail screen
            └── ContactDetailRouter.swift # Handles navigation to other features from contact detail # Feature for managing contact groups
    ├── ContactGroupList
        ├── Views # UI components for displaying contact groups
        │   └── ContactGroupListView.swift # Xcode Storyboard or SwiftUI view for contact group list
        ├── Interactors # Business logic for contact group data
        │   └── ContactGroupListInteractor.swift # Fetches, updates, and manages contact groups
        ├── Presenters # Prepares data for the contact group list view
        │   └── ContactGroupListPresenter.swift # Receives data from interactor and formats it for view
        └── Routers # Navigation logic for the contact group list screen
            └── ContactGroupListRouter.swift # Handles navigation to other features from contact group list # Feature for managing the list of contacts
    └── ContactList
        ├── Views # UI components for displaying contacts
        │   └── ContactListView.swift # Xcode Storyboard or SwiftUI view for contact list
        ├── Interactors # Business logic for contact data
        │   └── ContactListInteractor.swift # Fetches, updates, and manages contacts
        ├── Presenters # Prepares data for the contact list view
        │   └── ContactListPresenter.swift # Receives data from interactor and formats it for view
        └── Routers # Navigation logic for the contact list screen
            └── ContactListRouter.swift # Handles navigation to other features from contact list
├── App # Entry point and core application logic
│   ├── AppDelegate.swift # Manages the application lifecycle
│   ├── SceneDelegate.swift # Manages window scene lifecycle and transitions on iOS 13+
│   └── MainCoordinator.swift # Coordinates navigation between features
├── Tests # Unit tests for application components
│   ├── CommonTests # Tests for shared code
│       ├── ModelsTests.swift # Unit tests for `Contact` and `ContactGroup` models
│       └── UtilsTests.swift # Unit tests for `NetworkManager` and `StorageManager`
│   ├── FeaturesTests # Tests for individual features
│       ├── ContactDetailTests.swift # Unit tests for contact detail functionality
│       ├── ContactGroupListTests.swift # Unit tests for contact group list functionality
│       └── ContactListTests.swift # Unit tests for contact list functionality
│   └── AppTests # Tests for application entry point
│       └── AppDelegateTests.swift # Unit tests for `AppDelegate`
└── Resources # Assets and configuration files
    ├── Images.xcassets # App icons and other images
    ├── LaunchScreen.storyboard # Storyboard for the launch screen
    └── Info.plist # Configuration file for the application
```

## Shop App (Android)

```python
ShopApp
├── app
│   ├── build.gradle
│   ├── src
│       ├── main
│           ├── AndroidManifest.xml
│           ├── assets
│           │   └── ... # app assets like images
│           ├── java
│               └── com.yourcompany.shop
│                   ├── data
│                       ├── model
│                           ├── Product.java # Represents a product with details
│                           └── ProductCategory.java # Represents a product category
│                   ├── network
│                       └── ApiManager.java # Handles network communication
│                   ├── persistence
│                       └── LocalStorage.java # Handles data persistence on device
│                   ├── repository
│                       └── ProductRepository.java # Provides access to product data
│                   ├── features
│                       ├── productdetail  # Feature for managing a single product detail
│                       │   ├── contract
│                       │   │   ├── ProductDetailContract.kt # Interface for VIPER communication
│                       │   │       ├── ProductDetailView.kt # Interface for View
│                       │   │       ├── ProductDetailInteractor.kt # Interface for Interactor
│                       │   │       ├── ProductDetailPresenter.kt # Interface for Presenter
│                       │   │       └── ProductDetailRouter.kt # Interface for Router
│                       │   ├── data
│                       │   │   └── ProductDetailRepositoryImpl.kt # Implementation of ProductRepository for product detail
│                       │   ├── presentation
│                       │   │   ├── ProductDetailPresenterImpl.kt # Implementation of ProductDetailPresenter
│                       │   ├── ui
│                       │   │   └── ProductDetailActivity.kt # Activity for displaying product details
│                       │   └── ... (other implementation classes)
│                       ├── productlist  # Feature for managing the product list
│                       │   ├── contract
│                       │   │   ├── ProductListContract.kt # Interface for VIPER communication
│                       │   │       ├── ProductListView.kt # Interface for View
│                       │   │       ├── ProductListInteractor.kt # Interface for Interactor
│                       │   │       ├── ProductListPresenter.kt # Interface for Presenter
│                       │   │       └── ProductListRouter.kt # Interface for Router
│                       │   ├── data
│                       │   │   └── ProductListRepositoryImpl.kt # Implementation of ProductRepository for product list
│                       │   ├── presentation
│                       │   │   ├── ProductListPresenterImpl.kt # Implementation of ProductListPresenter
│                       │   ├── ui
│                       │   │   └── ProductListActivity.kt # Activity for displaying product list
│                       │   └── ...
│                   ├── ...
│                   └── util
│                       └── ... # Utility classes
│   └── gradle.properties
│   └── gradlew.bat  # or gradlew (depending on OS)
├── build.gradle
├── gradle.properties
└── local.properties # Optional for local development configuration
```