Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/saik0s/tca_tuist_boilerplate
https://github.com/saik0s/tca_tuist_boilerplate
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/saik0s/tca_tuist_boilerplate
- Owner: Saik0s
- Created: 2024-11-12T17:35:45.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2024-11-13T19:20:04.000Z (about 2 months ago)
- Last Synced: 2024-11-13T19:32:53.651Z (about 2 months ago)
- Language: Swift
- Size: 12.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# iOS Project Template with Tuist and The Composable Architecture (TCA)
An advanced, ready-to-use template for iOS applications, leveraging **Tuist** for scalable project management and **The Composable Architecture (TCA)** for robust state management. This template provides a modular and testable architecture, making it easier to build, maintain, and scale your iOS applications.
## Table of Contents
- [Overview](#overview)
- [Project Structure](#project-structure)
- [Tools and Technologies](#tools-and-technologies)
- [Tuist](#tuist)
- [The Composable Architecture (TCA)](#the-composable-architecture-tca)
- [Mise](#mise)
- [Swift Package Manager](#swift-package-manager)
- [Pre-commit Hooks](#pre-commit-hooks)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Setup](#setup)
- [Feature Module Template](#feature-module-template)
- [Using the Template](#using-the-template)
- [Feature Module Structure](#feature-module-structure)
- [Common Tasks](#common-tasks)
- [Tips](#tips)
- [Contributing](#contributing)
- [License](#license)## Overview
This template provides a solid foundation for developing iOS applications with a focus on scalability and maintainability. It utilizes **Tuist** to manage complex Xcode projects and **The Composable Architecture (TCA)** for predictable state management using SwiftUI. The project is structured to encourage modularity, making it easy to develop, test, and reuse features.
## Project Structure
The project is organized into several key directories and modules to promote modularity, testability, and scalability.
### High-level Structure
```plaintext
ProjectRoot/
├── TCATuistBoilerplate/ # Main app target
│ ├── Sources/ # App's source code
│ └── Resources/ # Assets, storyboards, etc.
├── Features/ # Feature modules
│ ├── ListScreen/ # Example feature module
│ │ ├── Sources/ # Implementation code
│ │ ├── Interface/ # Public API and models
│ │ ├── Testing/ # Test utilities and mocks
│ │ └── Tests/ # Unit and snapshot tests
│ └── [OtherFeatures]/ # Additional features
├── Libraries/ # Reusable libraries and components
│ ├── TaskProcessor/ # Async task processing library
│ └── Component/ # Reusable UI components
├── Tuist/ # Project generation configuration
│ ├── Templates/ # Templates for scaffolding
│ ├── Config.swift # Global configuration
│ ├── Dependencies.swift # SwiftPM dependencies
│ └── ProjectDescriptionHelpers/ # Shared helpers
├── Makefile # Common tasks automation
├── .mise.toml # Tool version management
├── .pre-commit-config.yaml # Pre-commit hooks configuration
└── README.md # Project documentation
```### Project Structure Diagram
Here's a Mermaid diagram representing the high-level project structure:
```mermaid
graph TD
subgraph ProjectRoot
subgraph App
TCATuistBoilerplate
end
subgraph Features
ListScreen
OtherFeatures
end
subgraph Libraries
TaskProcessor
Component
end
subgraph Tuist
Templates
Config[Config.swift]
Dependencies[Dependencies.swift]
Helpers[ProjectDescriptionHelpers]
end
Makefile
Mise[.mise.toml]
PreCommit[.pre-commit-config.yaml]
README[README.md]
end
TCATuistBoilerplate -->|Uses| Features
TCATuistBoilerplate -->|Uses| Libraries
Features -->|Depends on| Libraries
Tuist -->|Generates| TCATuistBoilerplate
Tuist -->|Generates| Features
Tuist -->|Generates| Libraries
```- **App (TCATuistBoilerplate)**: The main application target, responsible for app-level configurations and integrating features.
- **Features**: Independent, modular feature modules that encapsulate their own logic, views, and state management.
- **Libraries**: Reusable components and utilities that can be shared across features and the main app.
- **Tuist**: Contains configuration and templates for project generation and management using Tuist.
- **Makefile**, **.mise.toml**, **.pre-commit-config.yaml**: Tools for automating tasks, managing tool versions, and enforcing code quality standards.### Modules and Components
#### TCATuistBoilerplate/
This directory contains the main application target.
- **Sources/**: The main app's Swift code, including the `App` struct and entry point.
- **Resources/**: Assets, storyboards, and other resource files.
- **Project.swift**: Tuist configuration for the app target.
```swift
//
// Project.swift
//import ProjectDescription
import ProjectDescriptionHelperslet project = Project(
name: "TCATuistBoilerplate",
options: .options(
textSettings: .textSettings(
indentWidth: 2,
tabWidth: 2
)
),
targets: [
.target(
name: "TCATuistBoilerplate",
destinations: env.destinations,
product: .app,
bundleId: "\(env.organizationName).TCATuistBoilerplate",
deploymentTargets: env.deploymentTargets,
infoPlist: .extendingDefault(
with: [
"UILaunchScreen": [
"UIColorName": "",
"UIImageName": "",
],
]
),
sources: ["Sources/**"],
resources: ["Resources/**"],
dependencies: [
.project(target: "ListScreen", path: "../Features/ListScreen"),
.external(name: "ComposableArchitecture"),
]
),
.target(
name: "TCATuistBoilerplateTests",
destinations: env.destinations,
product: .unitTests,
bundleId: "\(env.organizationName).TCATuistBoilerplateTests",
deploymentTargets: env.deploymentTargets,
infoPlist: .default,
sources: ["Tests/**"],
resources: [],
dependencies: [.target(name: "TCATuistBoilerplate")]
),
]
)
```#### Features/
Contains independent feature modules, each following a consistent structure.
##### Example: ListScreen/
```plaintext
ListScreen/
├── Project.swift # Tuist project configuration
├── Interface/ # Public API (e.g., clients, models)
│ ├── ListScreenClient.swift
│ └── ListScreenModels.swift
├── Sources/ # Implementation of the feature
│ ├── ListScreenFeature.swift # TCA reducer and logic
│ ├── ListScreenView.swift # SwiftUI view
│ ├── ListScreenItemView.swift # Subview for list items
│ ├── ListScreenAddItemFeature.swift # Add item functionality
│ ├── ListScreenEditItemFeature.swift # Edit item functionality
│ └── LiveListScreenClient.swift # Live implementation of the client
├── Testing/ # Testing utilities and mocks
│ └── ListScreenTesting.swift
└── Tests/ # Unit and snapshot tests
├── ListScreenTests.swift
└── ListScreenSnapshotTests.swift
```**Key Concepts in ListScreen**:
- **State Management**: Uses TCA to manage state in a predictable way.
- **Dependency Injection**: Clients like `ListScreenClient` are injected, allowing for easy testing and mocking.
- **Modularity**: The feature is self-contained, promoting reusability.
- **Testing**: Includes unit tests and snapshot tests to validate functionality and UI.#### Libraries/
Reusable components and utilities that can be shared across features.
##### Example: TaskProcessor/
```plaintext
TaskProcessor/
├── Project.swift # Tuist project configuration
├── Interface/ # Public API
│ ├── TaskProcessorClient.swift
│ ├── TaskProcessorModels.swift
│ └── TaskProcessorOperation.swift
├── Sources/ # Implementation
│ ├── LiveTaskProcessorClient.swift
│ └── TaskManager.swift
└── Tests/
└── TaskProcessorTests.swift
```**Key Concepts in TaskProcessor**:
- **Concurrency**: Uses Swift concurrency (`async`/`await`) to handle asynchronous tasks.
- **Real-time Progress Tracking**: Provides progress updates via `AsyncStream`.
- **Task Control**: Allows tasks to be paused, resumed, or cancelled.
- **Testing**: Includes comprehensive tests to ensure correct behavior.#### Tuist/
Contains configurations and templates for project generation.
- **Templates/**: Custom templates for scaffolding new features and libraries.
- **Config.swift**: Global configuration for Tuist.
```swift
//
// Config.swift
//import ProjectDescription
let config = Config()
```
- **Dependencies.swift**: Swift Package Manager dependencies.
- **ProjectDescriptionHelpers/**: Shared helpers and settings.### Build Automation and Tooling
#### Makefile
Provides common `make` commands for tasks like bootstrapping the environment, generating the project, running tests, formatting code, etc.
```makefile
MISE=$(HOME)/.local/bin/mise
TUIST=$(MISE) x tuist -- tuistall: bootstrap project_file
bootstrap:
command -v $(MISE) >/dev/null 2>&1 || curl https://mise.jdx.dev/install.sh | sh
$(MISE) installgenerate:
$(TUIST) install
$(TUIST) generate --no-opencache:
$(TUIST) cache --external-only
$(TUIST) generate --no-openupdate:
$(TUIST) install --update
$(TUIST) generate --no-openformat:
$(MISE) x swiftlint -- swiftlint lint --force-exclude --fix .
$(MISE) x swiftformat -- swiftformat . --config .swiftformatlint:
$(MISE) x swiftlint -- swiftlint lint --force-exclude .test:
$(TUIST) testunit_test:
$(TUIST) test --skip-ui-testsclean:
rm -rf build
$(TUIST) clean.SILENT: all bootstrap generate cache update format lint test clean
```#### .mise.toml
Configuration file for Mise, managing specific tool versions used in the project.
```toml
[tools]
tuist = "4.33.0"
swiftlint = "0.54.0"
swiftformat = "0.53.3"
```#### .pre-commit-config.yaml
Defines pre-commit hooks using the `pre-commit` framework to automatically format code and check for code quality issues before commits.
```yaml
repos:
- repo: local
hooks:
- id: format-and-add
name: Format and Add Changes
entry: bash -c 'make format && git add -u'
language: system
pass_filenames: false
```## Tools and Technologies
### Tuist
[**Tuist**](https://tuist.io/) is a command-line tool that helps you maintain and scale Xcode projects. It allows you to define your project structure in Swift using `Project.swift` files and provides various benefits:
- **Pros**:
- Simplifies project generation and configuration.
- Encourages modularity and code reuse.
- Allows for project templates and scaffolding.
- Version control friendly since project settings are code and not binary files.- **Cons**:
- Requires learning the Tuist domain-specific language.
- Adds an additional build step (project generation).### The Composable Architecture (TCA)
[**TCA**](https://github.com/pointfreeco/swift-composable-architecture) is a library for building applications in a consistent and understandable way, using unidirectional data flow, mutation, and side effects.
- **Pros**:
- Provides a predictable state management pattern.
- Facilitates testing by isolating side effects.
- Encourages modularity and code reuse.- **Cons**:
- Introduces a learning curve due to its functional programming concepts.
- Can add boilerplate code for small features.### Mise
[**Mise**](https://mise.jdx.dev/) is a tool that manages tool versions and provides a consistent environment across development machines.
- **Pros**:
- Ensures all developers use the same tool versions.
- Simplifies environment setup for new developers.- **Cons**:
- Additional tool to install and manage.### Swift Package Manager (SwiftPM)
Used for dependency management, SwiftPM integrates third-party libraries into the project.
- **Pros**:
- Integrated into the Swift toolchain.
- Provides a standard way to manage dependencies.- **Cons**:
- Limited support for binary dependencies and resources compared to other managers like CocoaPods.### Pre-commit Hooks
The project includes pre-commit hooks for code formatting and linting using [SwiftLint](https://github.com/realm/SwiftLint) and [SwiftFormat](https://github.com/nicklockwood/SwiftFormat).
- **Pros**:
- Enforces code style and quality.
- Catches issues before code is committed.- **Cons**:
- Requires setup and can reject commits if not configured properly.## Getting Started
### Prerequisites
- **Xcode 15** or later.
- **macOS 13** or later.
- **[Mise](https://mise.jdx.dev/)** installed.
- **[Pre-commit](https://pre-commit.com/)** installed.### Setup
1. **Install Mise and Project Dependencies**
Install **Mise** to manage tool versions and project dependencies:
```bash
# Install Mise (manages tool versions)
curl https://mise.jdx.dev/install.sh | sh# Install project dependencies
make bootstrap
```2. **Generate the Xcode Project**
Use the `make` command to generate the Xcode workspace using Tuist:
```bash
make generate
```3. **Open the Project**
Open the generated `.xcodeproj` or `.xcworkspace` file in Xcode.
4. **Install Pre-commit Hooks**
Install and set up pre-commit hooks for code formatting and linting:
```bash
pip install pre-commit
pre-commit install
```## Feature Module Template
The project includes **Tuist templates** for generating feature modules and libraries. These templates streamline the creation of new features, ensuring consistency and adherence to the project's architecture.
### Using the Template
1. **Generate a New Feature Module**
Use the `tuist scaffold` command to create a new feature module:
```bash
tuist scaffold list_feature --name YourFeature
```This will create a new feature module at `Features/YourFeature/` with the following structure:
```plaintext
YourFeature/
├── Project.swift
├── Interface/
├── Sources/
├── Testing/
└── Tests/
```2. **Update Main App Dependencies**
Add your new feature to the main app's dependencies in `TCATuistBoilerplate/Project.swift`:
```swift
//
// Project.swift
//import ProjectDescription
import ProjectDescriptionHelperslet project = Project(
name: "TCATuistBoilerplate",
options: .options(
textSettings: .textSettings(
indentWidth: 2,
tabWidth: 2
)
),
targets: [
.target(
name: "TCATuistBoilerplate",
// ...
dependencies: [
.project(target: "YourFeature", path: "../Features/YourFeature"),
// Other dependencies...
]
),
// Other targets...
]
)
```3. **Implement Your Feature**
- **Sources/**: Write your feature's logic and views.
- **Interface/**: Define public interfaces and models.
- **Tests/**: Write unit and snapshot tests.
- **Testing/**: Include test utilities and mocks.### Feature Module Structure
```plaintext
YourFeature/
├── Project.swift # Feature module configuration
├── Interface/ # Public API and models
│ ├── YourFeatureClient.swift
│ └── YourFeatureModels.swift
├── Sources/ # Implementation code
│ ├── YourFeatureFeature.swift
│ ├── YourFeatureView.swift
│ ├── YourFeatureItemView.swift
│ ├── YourFeatureAddItemFeature.swift
│ ├── YourFeatureEditItemFeature.swift
│ └── LiveYourFeatureClient.swift
├── Testing/ # Test utilities and mocks
│ └── YourFeatureTesting.swift
└── Tests/ # Unit and snapshot tests
├── YourFeatureTests.swift
└── YourFeatureSnapshotTests.swift
```### Creating a Library Module
Similarly, you can create a new library module using the provided template:
```bash
tuist scaffold task_processor_library --name YourLibrary
```This will create a library module at `Libraries/YourLibrary/` with the following structure:
```plaintext
YourLibrary/
├── Project.swift
├── Interface/
├── Sources/
└── Tests/
```## Common Tasks
### Update Dependencies
To update project dependencies (including Tuist and SwiftPM packages):
```bash
make update
```### Run Tests
Run all tests:
```bash
make test
```Run only unit tests:
```bash
make unit_test
```### Format Code
Format all Swift code using SwiftFormat and SwiftLint:
```bash
make format
```### Lint Code
Check code style and issues without fixing:
```bash
make lint
```### Clean Build Files
Clean the project's build artifacts:
```bash
make clean
```### Cache External Dependencies
Cache external dependencies to speed up build times:
```bash
make cache
```## Tips
- **Use Mise for Consistent Environments**: Mise ensures that all developers use the same versions of tools, which helps prevent inconsistencies and "works on my machine" issues.
- **Leverage Pre-commit Hooks**: Install and configure pre-commit hooks to enforce code quality standards automatically.
- **Understand TCA Concepts**: Familiarize yourself with reducers, actions, state, and effects in TCA to effectively implement features.
- **Modularize Your Code**: Keep your features and components modular. This makes your codebase more maintainable and testable.
- **Write Tests Early**: Leverage TCA's testability to write unit and integration tests as you develop new features.
- **Leverage Tuist Templates**: Use the provided Tuist templates to scaffold new features and components. This ensures consistency across your codebase.
- **Regularly Update Dependencies**: Keep your dependencies up to date to benefit from the latest features and bug fixes.
- **Document Your Code**: Maintain clear documentation within your code to make it easier for others (and future you) to understand.## Contributing
Contributions are welcome! Please follow these steps to contribute:
1. **Fork the Repository**: Create a personal fork of the repository on GitHub.
2. **Create a Feature Branch**: Make your changes in a new branch.
```bash
git checkout -b feature/your-feature
```3. **Commit Your Changes**: Ensure your commits are well-documented.
4. **Open a Pull Request**: Submit your changes for review.
5. **Code Review**: Participate in the review process and make any necessary changes.
## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
## Additional Resources
- **Tuist Documentation**: [https://docs.tuist.io/](https://docs.tuist.io/)
- **The Composable Architecture**: [https://github.com/pointfreeco/swift-composable-architecture](https://github.com/pointfreeco/swift-composable-architecture)
- **Mise Documentation**: [https://mise.jdx.dev/](https://mise.jdx.dev/)
- **SwiftLint**: [https://github.com/realm/SwiftLint](https://github.com/realm/SwiftLint)
- **SwiftFormat**: [https://github.com/nicklockwood/SwiftFormat](https://github.com/nicklockwood/SwiftFormat)
- **Pre-commit**: [https://pre-commit.com/](https://pre-commit.com/)