Generating Xcode Projects
Xcode is very sensitive to the project’s housekeeping files stored under .xcworkspace and .xcodeproj. For a solo
developer working on a single machine, this isn’t much of a problem. But once again — we’re talking about teamwork.
That’s exactly why it’s important for us to achieve transparent project portability and reproducible builds across all
developer machines and CI nodes.
The main problem with teamwork on iOS apps comes down to merge conflicts. And while conflicts in source code are
relatively easy to resolve, conflicts in housekeeping files always drive developers to despair. To avoid such problems,
people resort to project generators and exclude the housekeeping files themselves from version control.
In the simplest case, two lines are added to your .gitignore:
*.xcodeproj
*.xcworkspace
Today there are two well-known and actively maintained solutions for generating Xcode projects:
XcodeGen
XcodeGen is a tool for declarative project generation based on a yaml specification. It very much follows the Unix philosophy and does exactly one thing well — generates the project.
As always, when picking a tool you need to look beyond tutorials and try it out on real tasks.
Describing a project with yaml turns out to be a fairly hard task in practice. The specification is scattered across
md files in the project’s repository, and the comments on fields aren’t always clear and require additional digging.
Even a simple project consisting of a single screen is fairly hard to describe correctly on the first try.
Overall, based on my experience with it, I wouldn’t rush to recommend XcodeGen.
Tuist
Tuist offers much more flexibility by describing the project’s structure in Swift. In addition to project
generation, Tuist provides a command-line interface for:
- running the build,
- running tests,
- migrating an existing project onto
Tuist, - creating your own plugins, and
- scaffolding micro-features, which we’ll talk about in the notes on architecture.
Tuist is a significantly more flexible tool than XcodeGen.
And in the general case, I’d prefer to use it.
That said, let me offer a word of warning. At the time of writing this post, the Tuist documentation is being
actively reworked. The internal project-description API has also changed. The out-of-the-box templates will be
highlighted in yellow because many methods are marked deprecated. This will require you to be ready to dive into the sources and dig through issues on GitHub.
But none of this makes the tool unusable; it only underscores the team’s active work on it.
Code examples
It’s better to run it once than to read about it a hundred times. For this blog I created a group on GitLab:
and posted examples of simple apps that use project generation via XcodeGen and Tuist:
https://gitlab.com/towards-head-of-mobile-engineering/showcase/xcode-project-generation
In the examples the project structure is significantly simplified, with only a single build target. This is done purely for clarity.