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:

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:

https://gitlab.com/towards-head-of-mobile-engineering

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.