- Getting started
- Project description
- Project description helpers
- App Extensions
- Accessing resources
- Third-party dependencies
- Caching dependencies
- Microfeatures architecture
- Managing versions
- Adoption guidelines
- Best practices
- Frequently asked questions
- Edit your projects
- Generate projects
- Focus on targets
- Sign your apps
- Build schemes
- Scaffold files
- Project graph
- Set up environment
- Migrate Xcode projects
- Generate documentation
- Generate secrets
- Clean the local environment
Although Tuist defaults to some conventions on the projects that are initialized with Tuist, its API doesn’t enforce them purposedly to ease the adoption of the tool. Very often, Xcode projects end up being complex because Xcode is weakly opinionated about the project structure. As long as the build system is able to process build settings and phases and output valid, it’s all good.
Complex and non-conventional projects are undesirable because they are hard to reason about and might lead to compilation errors. The result of that is that only a few people in the team can make well-informed decisions to scale up the project. In other words, your team ends up with a high bus factor.
The good news is that Tuist is an excellent tool to codify conventions: how files are structured in frameworks, how frameworks should be named, how resources should be bundled. Although they are not necessary to benefit from Tuist, we encourage spending some time defining them for your project and codifying them in your project manifests.
This document contains a list of recommendations for conventions that we’d follow to ease scaling up your projects.
- Explicit definition: Dependencies can be defined implicitly through build settings. Xcode is smart enough to detect them and determine the order in which targets should be built. Although implicitness might work fine in small projects, as they get larger, it might turn into a source of issues and slowness. Default to explicit definition of dependencies using the dependencies API that Tuist provides. Tuist has handy built-in features such as tuist graph or detection of circular dependencies that rely on dependencies being explicitly defined.
- XCTest dependency: If a target that is not a test target depends on
XCTest, declare the dependency explicitly with
- Keep it simple: Although the API for defining a list of files is very flexible, we discourage having a complex file structure because they increase the project generation time and make it hard for developers to spot at glance what belongs to what. A complex file structure is a structure where files of different nature are placed alongside and require the usage of glob patterns and excluded files that are expensive to resolve.
// Recommendedlet target = Target(name: "MyFramework", sources: ["MyFramework/Sources"])// Discouragedlet target = Target(name: "MyFramework", sources: ["MyFramework/**/*.swift"])
Using on CI
tuist to your project will require you to have installed it in your CI system. You can avoid it by bundling specific version in your repo:
- Define your local version:
tuist local 1.7.1
- Bundle it:
- Commit the added files into git
.tuist-bin/tuist generatein your CI
Workspace.swift vs Project.swift
Even though we support aggregating multiple projects into a workspace using the
We recommend one project with multiple targets over one workspace with multiple projects.
Having an Xcode workspace is useful when projects are part of the Git repository because it helps reduce the likelihood of conflicts.
However, that’s not an issue in Tuist because projects don’t need to be part of the repository.
Moreover, having a single project allows using the focus feature to generate optimized projects with dependencies from the cache.