Using tuist for building a workspace

Gerhard Schneider
Level Up Coding
Published in
4 min readMar 15, 2021

--

While tuist is an extremely useful tool, the documentation is missing some showcases that illustrate in which ways workspaces can be set up. The default project that can be created with tuist itself just creates a workspace, where the various targets are folders below.

However, when thinking of frameworks it’d be nice to have an Xcode workspace where each framework is an Xcode project on its own. It took me some efforts to figure out how this can be achieved. This video from Pedro Buendia delivered the final clue, and in the end, it’s pretty simple.

So, let me explain what to do, in order to save you some time.

I assume that you know how to use a terminal, and that you already did your first steps with tuist. Because I’ll focus on the tuist aspects, I will not get into the code used for this demonstration app and its frameworks.

First, we need a folder where we can work in. Take the Terminal and create a folder tmp. Perform a tuist init so that the folder is set up accordingly. Finally, perform a tuist edit -P for getting a persistent manifest project that we can open and edit easily.

Next, we need a workspace definition. Create a file Workspace.swift in the manifest folder and put this content in:

This defines a workspace named MyAppWS that shall contain three projects called TmpApp, A and B, where one shall be the app (guess which one…), and the other two shall be frameworks.

When opening the manifest in Xcode, create some groups and files so that it looks like this:

To explain this step: We create a folder “Projects”, and subfolders for each project we want to create (“TmpApp”, “A” and “B”). We need those for creating a Project.swift file in each of them; we’ll come back to that in a moment.

The “Sources” folders are required to provide the sources that shall be part of the projects. However, they just have to exist on disk, but not necessarily in the Manifests project; we do this just for purpose of this article.

Now that we have the basic structures we need, we need some content in the project manifests.

First, the app’s manifest:

This is just a standard project definition; the important part is the dependencies property that we set to a .project , in this case “A”, because we need the framework “A” for the app to run. The path is relative to the manifest.

Next, we provide the manifest for framework “A”:

Here, the same game as before, but not as product .app as before, but as .framework . Because “A” needs “B” to work, we add here a dependency as well, in the same manner as before.

Finally, the manifest for framework “B”:

We just vary a bit, using a .staticFramework here, with no more dependencies.

For the production code (i.e., the Swift files for the app and the frameworks themselvers), you may put it whatever you want.

So now, when performing a tuist generate --open, you will see this result:

A nice, clean workspace structure, with a project for each of the projects, app and frameworks. When performing an import A in the App.swift code, and an import B in the A.swift code, this will build perfectly.

As a nice side-effect, you can use tuist to generate an overview graph of the dependencies by performing tuist graph:

So, we’re done. When you’ll try to reconstruct what I did you’ll probably notice that we have to take care of the target memberships of the manifest files.

While the Workspace.swift file must be member of the *Manifests target, the project’s Project.swift files must not be member of any target. Otherwise, there will be Xcode errors because of the duplicate file names.

I also noticed that the syntax highlighting and code completion features of Xcode are working for the top-level manifest files, but not for the lower-level manifests in the projects. I assume that this is a kind of bug, but perhaps there is a different reason — if you know how to fix this, let me know!

Thank you for reading this small article, please don’t forget to clap if you found it useful.

--

--

Helping companies and humans to evolve by opening new perspectives on the management of products and portfolios.