Skip to content

tddworks/SwiftUITemplate

Repository files navigation

SwiftUITemplate - Modular Architecture

A comprehensive Tuist template for building SwiftUI projects with modular architecture, supporting apps, frameworks, and extensions.

πŸš€ Features

  • Modular Architecture: Clean separation between apps, frameworks, modules, and extensions
  • Multiple Target Types: Support for apps, frameworks (static/dynamic), and various app extensions
  • SwiftUI Ready: Templates come with SwiftUI boilerplate code
  • Configurable: Flexible configuration options for each target type
  • Test Support: Automatic test target generation with configurable options
  • Organized Structure: Pre-configured folder structure for easy project maintenance

πŸ› οΈ Getting Started

1. Add the Template to Your Project

Add this template as a Tuist plugin in your Project.swift:

import ProjectDescription

let tuist = Tuist(
    project: .tuist(plugins: [
        .git(url: "https://github.com/tddworks/SwiftUITemplate", tag: "v1.1.0")
    ])
)

2. Available Templates

Template Types:

  • Initial Templates: Use these for creating new projects (app, framework, module, extension, workspace)
  • Addition Templates: Use these for adding to existing projects (addapp, addframework, addmodule, addextension)

The addition templates are safer as they never overwrite existing project configuration files.

Create a New SwiftUI App

Generate a new SwiftUI application:

tuist scaffold app --name MyApp --platform ios --bundle-id com.example --team-id ABC123XYZ --version 1.0.0

Options:

  • name (required): App name
  • platform: Target platform (ios/macos)
  • bundle-id: Bundle identifier prefix
  • team-id: Development team ID for code signing
  • version: App version
  • has-tests: Include test target (default: true)
  • has-ui-tests: Include UI test target (default: false)

Resulting Structure:

Root/
β”œβ”€β”€ Tuist/ProjectDescriptionHelpers/Targets/Products/MyApp.swift
β”œβ”€β”€ Products/
β”‚   β”œβ”€β”€ MyApp/
β”‚   β”‚   β”œβ”€β”€ Resources/
β”‚   β”‚   β”‚   β”œβ”€β”€ Assets.xcassets
β”‚   β”‚   β”‚   └── InfoPlist.strings
β”‚   β”‚   β”œβ”€β”€ Sources/
β”‚   β”‚   β”‚   β”œβ”€β”€ MyAppApp.swift
β”‚   β”‚   β”‚   └── ContentView.swift
β”‚   β”‚   └── Tests/
β”‚   β”‚       └── MyAppTests.swift
└── Project.swift

Create a Framework

Generate a reusable framework:

tuist scaffold framework --name Core --is-static false --has-resources true

Options:

  • name (required): Framework name
  • is-static: Create static framework (default: false)
  • has-resources: Include resources (default: false)
  • has-tests: Include test target (default: true)
  • dependencies: Array of dependencies

Resulting Structure:

Root/
β”œβ”€β”€ Tuist/ProjectDescriptionHelpers/Targets/Frameworks/Core.swift
β”œβ”€β”€ Frameworks/
β”‚   β”œβ”€β”€ Core/
β”‚   β”‚   β”œβ”€β”€ Resources/
β”‚   β”‚   β”œβ”€β”€ Sources/
β”‚   β”‚   β”‚   β”œβ”€β”€ Core.swift
β”‚   β”‚   β”‚   └── CoreInterface.swift
β”‚   β”‚   └── Tests/
β”‚   β”‚       └── CoreTests.swift

Create a Module

Generate a feature module:

tuist scaffold module --name FeatureAuth

Resulting Structure:

Root/
β”œβ”€β”€ Tuist/ProjectDescriptionHelpers/Targets/Modules/FeatureAuth.swift
β”œβ”€β”€ Modules/
β”‚   └── FeatureAuth/
β”‚       β”œβ”€β”€ Resources/
β”‚       └── Sources/
β”‚           └── FeatureAuth.swift

Create an Extension

Generate an app extension:

tuist scaffold extension --name MyWidget --type widget --host-app MyApp

Options:

  • name (required): Extension name
  • type (required): Extension type (widget, notification, share, etc.)
  • host-app (required): Host app name
  • bundle-id: Bundle identifier prefix
  • version: Extension version
  • has-ui: Include UI components (default: true)

Available Extension Types:

  • widget: Widget Extension
  • notification: Notification Service Extension
  • action: Action Extension
  • share: Share Extension
  • today: Today Extension
  • intents: Intents Extension
  • intentui: Intents UI Extension
  • fileprovider: File Provider Extension
  • fileproviderui: File Provider UI Extension

Add App to Existing Project

Add additional app targets to an existing project:

tuist scaffold addapp --name DemoApp --platform macos --bundle-id com.mycompany.demo

Options:

  • name (required): New app name
  • platform: Target platform (ios, macos, watchos, tvos) (default: ios)
  • bundle-id: Bundle identifier prefix (default: com.example)
  • version: App version (default: 1.0.0)
  • has-tests: Include test target (default: true)
  • has-ui-tests: Include UI test target (default: false)

Notes:

  • Use addapp only after creating the initial project with app template
  • Does not overwrite existing Project.swift or Tuist configuration
  • Automatically creates app target definition files
  • Supports multiple platforms in same project (iOS + macOS + watchOS + tvOS)

Add Framework to Existing Project

Add additional framework targets to an existing project:

tuist scaffold addframework --name NetworkLayer --has-resources false --is-static false

Options:

  • name (required): Framework name
  • platform: Target platform (ios, macos, watchos, tvos) (default: ios)
  • has-resources: Include resources (default: false)
  • has-tests: Include test target (default: true)
  • is-static: Create static framework (default: false)

Add Module to Existing Project

Add additional module targets to an existing project:

tuist scaffold addmodule --name UserProfile

Options:

  • name (required): Module name

Add Extension to Existing Project

Add additional extension targets to an existing project:

tuist scaffold addextension --name MyWidget --type widget --host-app MyApp

Options:

  • name (required): Extension name
  • type (required): Extension type (widget, notification, share, etc.)
  • host-app (required): Host app name
  • bundle-id: Bundle identifier prefix (default: com.example)
  • version: Extension version (default: 1.0.0)
  • has-ui: Include UI components (default: true)

Safe Addition Templates:

  • All add* templates are designed for existing projects
  • They never overwrite Project.swift, Package.swift, or Tuist/ configuration
  • Safe to use multiple times to incrementally build your project

Create a Workspace (Multi-App Support)

Generate a workspace supporting multiple app targets:

tuist scaffold workspace --name MyWorkspace --apps "MainApp,CompanionApp,AdminApp"

Options:

  • name (required): Workspace name
  • apps (required): Comma-separated list of app names
  • bundleIdPrefix: Bundle identifier prefix (default: com.example)
  • structure: Project structure - "single" or "multi" (default: multi)
  • sharedFrameworks: Array of shared frameworks (default: ["Core", "Shared"])
  • version: Version number (default: 1.0.0)

Structure Options:

  • single: All apps in one project file
  • multi: Separate project per app in workspace (recommended)

Add App to Existing Workspace

Add a new app to an existing workspace:

tuist scaffold multiapp --name NewApp --workspace MyWorkspace

Options:

  • name (required): New app name
  • workspace (required): Existing workspace name
  • bundleIdPrefix: Bundle identifier prefix
  • sharedDependencies: Dependencies on shared frameworks

3. Complete Example Workflows

Single App Project

# 1. Create the main app and project structure
tuist scaffold app --name MyApp --platform ios --bundle-id com.mycompany --team-id ABC123XYZ

# 2. Generate initial project
tuist generate

# 3. Add components safely to existing project
tuist scaffold addframework --name Core --has-resources false
tuist scaffold addframework --name NetworkLayer --has-resources false

# 4. Add feature modules  
tuist scaffold addmodule --name Authentication
tuist scaffold addmodule --name UserProfile
tuist scaffold addmodule --name Settings

# 5. Add extensions
tuist scaffold addextension --name MyWidget --type widget --host-app MyApp
tuist scaffold addextension --name MyCloudSync --type fileprovider --host-app MyApp

# 6. Add additional apps to the same project (optional)
tuist scaffold addapp --name MyApp1 --platform macos --bundle-id com.mycompany.macos
tuist scaffold addapp --name DemoApp --platform ios --bundle-id com.mycompany.demo

# 7. Generate final project with all components
tuist generate

Multi-App Workspace

# 1. Create workspace with multiple apps
tuist scaffold workspace --name MyWorkspace --apps "MainApp,AdminApp,CompanionApp" --bundleIdPrefix com.mycompany

# 2. Add additional frameworks to shared project
tuist scaffold framework --name NetworkLayer --hasResources false
tuist scaffold framework --name DatabaseLayer --hasResources false

# 3. Add more apps later
tuist scaffold multiapp --name DebugApp --workspace MyWorkspace --sharedDependencies "Core,Shared,NetworkLayer"

# 4. Add extensions for specific apps
tuist scaffold extension --name MainAppWidget --type widget --hostApp MainApp
tuist scaffold extension --name AdminDashboard --type today --hostApp AdminApp

# 5. Generate the workspace
tuist generate

Single Project with Multiple Apps

# 1. Create single project with multiple apps
tuist scaffold workspace --name MyProject --apps "MainApp,CompanionApp" --structure single --bundleIdPrefix com.mycompany

# 2. Generate the project
tuist generate

πŸ“ Project Structure

Single App Project

.
β”œβ”€β”€ Products/          # App targets
β”œβ”€β”€ Modules/           # Feature modules
β”œβ”€β”€ Frameworks/        # Shared frameworks
β”œβ”€β”€ Extensions/        # App extensions
β”œβ”€β”€ Tuist/            # Tuist configuration
β”‚   └── ProjectDescriptionHelpers/
β”‚       β”œβ”€β”€ Targets/
β”‚       β”‚   β”œβ”€β”€ Products/    # App target definitions
β”‚       β”‚   β”œβ”€β”€ Modules/     # Module target definitions
β”‚       β”‚   β”œβ”€β”€ Frameworks/  # Framework target definitions
β”‚       β”‚   └── Extensions/  # Extension target definitions
β”‚       β”œβ”€β”€ TargetFactory.swift
β”‚       β”œβ”€β”€ TargetExtensions.swift
β”‚       β”œβ”€β”€ SourcePaths.swift
β”‚       └── SettingsFactory.swift
└── Project.swift

Multi-App Workspace (Recommended)

MyWorkspace/
β”œβ”€β”€ MyWorkspace.xcworkspace/
β”œβ”€β”€ MainApp/
β”‚   β”œβ”€β”€ Sources/
β”‚   β”œβ”€β”€ Resources/
β”‚   β”œβ”€β”€ Tests/
β”‚   └── Project.swift
β”œβ”€β”€ AdminApp/
β”‚   β”œβ”€β”€ Sources/
β”‚   β”œβ”€β”€ Resources/
β”‚   β”œβ”€β”€ Tests/
β”‚   └── Project.swift
β”œβ”€β”€ CompanionApp/
β”‚   β”œβ”€β”€ Sources/
β”‚   β”œβ”€β”€ Resources/
β”‚   β”œβ”€β”€ Tests/
β”‚   └── Project.swift
β”œβ”€β”€ Shared/            # Shared frameworks project
β”‚   β”œβ”€β”€ Frameworks/
β”‚   β”‚   β”œβ”€β”€ Core/
β”‚   β”‚   └── Shared/
β”‚   └── Project.swift
β”œβ”€β”€ Tuist/
β”‚   β”œβ”€β”€ Config.swift
β”‚   └── ProjectDescriptionHelpers/
β”‚       β”œβ”€β”€ WorkspaceFactory.swift
β”‚       β”œβ”€β”€ TargetFactory.swift
β”‚       └── ...
└── Workspace.swift

Single Project with Multiple Apps

.
β”œβ”€β”€ Products/
β”‚   β”œβ”€β”€ MainApp/
β”‚   β”œβ”€β”€ AdminApp/
β”‚   └── CompanionApp/
β”œβ”€β”€ Frameworks/        # Shared frameworks
β”œβ”€β”€ Modules/           # Feature modules
β”œβ”€β”€ Extensions/        # App extensions
β”œβ”€β”€ Tuist/            # Tuist configuration
└── Project.swift      # Contains all apps

Special Extension Types

File Provider Extensions

File Provider extensions allow your app to provide files to the Files app and other document-based apps. Two types are supported:

File Provider Extension

  • Provides file enumeration and management capabilities
  • Handles file operations like create, read, update, delete
  • Integrates with the Files app and document picker
tuist scaffold extension --name MyCloudProvider --type fileprovider --host-app MyApp

File Provider UI Extension

  • Provides custom UI for file provider actions
  • Handles user interactions for file operations
  • Works in conjunction with File Provider Extension
tuist scaffold extension --name MyCloudProviderUI --type fileproviderui --host-app MyApp

Generated Features:

  • Complete FileProviderExtension class with item management
  • File enumeration and sync anchor support
  • SwiftUI-based action interface for UI extension
  • Proper entitlements for file system access
  • App group configuration for data sharing

Target Factory Methods

The project provides a comprehensive TargetFactory with methods for creating different target types:

App Targets

  • createAppTarget(): Creates an app target
  • createAppTestTarget(): Creates app unit tests

Framework Targets

  • createFramework(): Creates a dynamic framework
  • createStaticFramework(): Creates a static framework
  • createFrameworkTests(): Creates framework tests

Extension Targets

  • createExtension(): Creates an app extension with configurable type

Configuration

Edit Config.swift to modify:

  • Compatible Xcode versions
  • Swift version
  • Generation options

Each target type can be configured with:

  • Bundle identifiers
  • Destinations (iOS, macOS, etc.)
  • Resources
  • Dependencies
  • Build settings

Best Practices

  1. Modular Development: Break your app into feature modules for better code organization
  2. Shared Code: Use frameworks for code shared between targets
  3. Multi-App Architecture: Choose the right structure for your needs:
    • Workspace with separate projects: Best for complex apps with different lifecycles
    • Single project: Good for related apps sharing most code
  4. Shared Frameworks: Create Core for business logic, Shared for UI components
  5. Extensions: Keep extension code minimal and focused
  6. File Provider: Use File Provider extensions for cloud storage integration
  7. Testing: Always include test targets for critical components
  8. Dependencies: Use explicit dependencies between modules
  9. Bundle IDs: Use consistent bundle ID prefixes across all apps in workspace
  10. Schemes: Create separate schemes for each app target for easier development

Multi-App Scenarios

When to use Multiple Apps:

  • Main app + Admin/Debug companion app
  • Consumer app + Business/Enterprise variant
  • iOS app + macOS app sharing code
  • Different deployment targets (App Store vs Enterprise)
  • A/B testing different app experiences

Workspace vs Single Project:

  • Use Workspace: When apps have different release cycles, teams, or significant differences
  • Use Single Project: When apps are closely related and developed together

πŸ“š Learn More


🀝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to open an issue or submit a pull request.


πŸ“„ License

This project is licensed under the MIT License.

About

Tuist template

Resources

License

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

No packages published