Setting up Tuist 4 to your existing project

Lee young-jun
9 min readMar 20, 2024

--

I decided to create a new app. Nowadays Tuist is a famous tool among iOS developers. So I confirmed to apply it to initial project.

Installation

The author recommends mise instead of brew. However you can use brew if you ignore versioning issue.

mise

When I ran mise install tuist. The system complained to me.

-bash: mise: command not found

So I had to install mise first.

brew install mise

And ran mise again

mise install tuist

Mise seem’s like virtual machine?

You can specify version like tuist@x.x.x.

So installation is done? Nope, I should execute command to use Tuist in the current directory.

mise use tuist

This will specify lastest version, but likewise the installation you can specify version.

Running Tuist

The next item of Installation is Project structure.

There was not usage. What’s next?
Fortunately there is tutorials.

Tutorial displays rtx. But when I pressed rtx link, it navigated to mise repository, it was migrated.

I skipped installation, because I already installed Tuist.

However I can’t run Tuist command

-bash: tuist: command not found

Tuist is installed on mise. So I had to run it on mise. I checked usage first.

mise --help

mise x -- npm install `npm install` w/ config loaded into PATH

mise x -- tuist version

4.6.0

it works now!

Migration

I explored there is a way to migrate existing Xcode project.
Fortunately there is migration command

The guide has Migration guidelines, but I couldn’t see anything.

I found old migration guide, because version 4 guide is not ready??

Anyway I tried migration command.

settings-to-xcconfig

I ran --help option of migration to display the usage.

mise x — tuist migration — help

OVERVIEW: A set of utilities to assist in the migration of Xcode projects to Tuist.

USAGE: tuist migration <subcommand>

OPTIONS:
-h, --help Show help information.

SUBCOMMANDS:
settings-to-xcconfig It extracts the build settings from a project or a target into an xcconfig file.
check-empty-settings It checks if the build settings of a project or target are empty. Otherwise it exits unsuccessfully.
list-targets It lists the targets of a project sorted by number of dependencies.

See 'tuist help migration <subcommand>' for detailed help.

And also displayed the usage of first subcommand settings-to-xcconfig

mise x --tuist help migration settings-to-xcconfig

OVERVIEW: It extracts the build settings from a project or a target into an xcconfig file.

USAGE: tuist migration settings-to-xcconfig --xcodeproj-path <xcodeproj-path> --xcconfig-path <xcconfig-path> [--target <target>]

OPTIONS:
-p, --xcodeproj-path <xcodeproj-path>
The path to the Xcode project
-x, --xcconfig-path <xcconfig-path>
The path to the .xcconfig file where build settings will be extracted.
-t, --target <target> The name of the target whose build settings will be extracted. When not passed, it extracts the
build settings of the project.
-h, --help Show help information.

By following the usage, it can’t migrate project automatically. It just assistances migration.

I created xcconfig file with the command.

mise x -- tuist migration settings-to-xcconfig -p {Project Name}.xcodeproj -x {xcconfig name}.xcconfig -t {Target Name}

A new .xcconfig created.

ASSETCATALOG_COMPILER_APPICON_NAME=AppIcon
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME=AccentColor
CURRENT_PROJECT_VERSION=1
DEVELOPMENT_ASSET_PATHS="queensbladelimithelper/Preview Content"
ENABLE_PREVIEWS=YES
GENERATE_INFOPLIST_FILE=YES
INFOPLIST_KEY_UIApplicationSceneManifest_Generation=YES
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents=YES
INFOPLIST_KEY_UILaunchScreen_Generation=YES
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad=UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight
...

check-empty-settings

Second sub command is explained like this.

It checks if the build settings of a project or target are empty. Otherwise it exits unsuccessfully.

I don’t what it is yet. Maybe check the build setting item is using default value.

When I ran it

mise x — tuist migration check-empty-settings -p {Project Name}.xcodeproj -t {Target Name}

I saw this result.

list-targets

Last sub command lists dependencies.

mise x — tuist migration list-target -p {Project Name}.xcodeproj

Creating Package.swift

What’t next? I should create Package.swift manually? There is no command to create Package.swift from Xcode project.

Create initial Project

One way is copying a file from initial project. Run this command to create new Tuist project.

mise x -- tuist init --platform ios

However before, I had to run this first.

mise use tuist

Otherwise you will see this error.

I moved the generated Package.swift into my Project directory.

Copying Tutorial

Second way is copying the file content from Tutorial.

Moving Files

Sources

Like initial project, I created Sources Directory and moved all Swift files into there.

Resources

Resource files also should be moved into the directory for resources.

Tests

Configuring Package.swift

After creating Package.swift or copying it, I set the project conforming to my project.

import ProjectDescription

let project = Project(
name: "{Your Project Name}",
targets: [
.target(
name: "{Your Target Name}",
destinations: .iOS,
product: .app,
bundleId: "{target package name}",
infoPlist: .extendingDefault(
with: [
"UILaunchStoryboardName": "LaunchScreen.storyboard",
]
),
sources: ["{Relative Path to Directory containing Source Files}/**"],
resources: ["{Relative Path to Directory containing Resource Files}/**"],
dependencies: []
),
.target(
name: "{Test Target name}",
destinations: .iOS,
product: .unitTests,
bundleId: "{test target package name}",
infoPlist: .default,
sources: ["{Relative Path to Directory containing Test Files}/**"],
resources: [],
dependencies: [.target(name: "{Your Target Name}")]
),
]
)

Editing Project

Next, I removed all files except Sources, Resources, Package.swift.
Now there is no xcodeproj. How can I implement app? I should create a project will not be pushed into Git?

Tuist supports creating a temporary project. Run this command.

mise x --tuist edit

But I could see only Project.swift, no sources, resources. This is project only for Project configuration. 🤣

Generating Project

edit command displays only project settings.

Instead I ran generate command. Usage is like this.

OVERVIEW: Generates an Xcode workspace to start working on the project.

USAGE: tuist generate [--path <path>] [<sources> ...] [--no-open] [--no-binary-cache] [--configuration <configuration>]

ARGUMENTS:
<sources> A list of targets to focus on. Other targets will be linked as binaries if possible. If no target
is specified, all the project targets will be generated (except external ones, such as Swift
packages).

OPTIONS:
-p, --path <path> The path to the directory or a subdirectory of the project.
-n, --no-open Don't open the project after generating it.
--no-binary-cache Ignore binary cache and use sources only.
-c, --configuration <configuration>
Configuration to generate for.
-h, --help Show help information.

mise x -- tuist generate

Now I can see source files.

Build Configuration

SwiftUI Preview is working as well. However signing team is empty. The project is temporary, how to upload configuration?

You might remember I created xcconfig before.

I moved the .xcconfig file into Configs directory and renamed it app.xcconfig.

To apply this configuration to target, I appended settings property.

let project = Project(
...,
targets: [
.target(
...,
settings: .settings(configurations: [
.debug(
name: "Debug",
xcconfig: "Configs/app.xcconfig")
])
),

Now Team is back.

To configure Release also, append .release into configurations .

settings: .settings(configurations: [
...,
.release(
name: "Release",
xcconfig: "Configs/app.xcconfig")
])

Maybe you want to split xcconfig files. Clone xcconfig and rename like app.debug.xcconfig, app.release.xcconfig

After regenerating, I could see configurations are splited.

When I configured dev, qa, deploy, configurations had also debug, release.

If your project is SwiftUI, you must modify Preview Asset path in xcconfig.

DEVELOPMENT_ASSET_PATHS="Resources/Preview Content"

Swift Package Manager

I will use Swift Package.

But it had been disappeared after generating again with Tuist. How can I install package via Tuist?

I read documentation os dependencies and followed. Of course there is tutorial for this case.

Package.swift

To install packages, I created Package.swift like Project.swift.

And copied content from the tutorial.

Now I can see Package.swift on tuist edit, then I modified the file to install my Swift Package.

And Project.swift

dependencies: [.package(product: "PackageName", type: .plugin)],
settings: ...

Lastly run installing Packages.

mise x --tuist install

I tried to generate project, however I encountered this error.

I just removed the line, but I couldn’t import the Package.

I didn’t know what’s wrong. So I used another way.
The way is to install package from Project directly.

packages

I removed Package.swift and modified Project.swift again.

let project = Project(
...,
packages: [.remote(
url: "https://github.com/2sem/LSExtensions",
requirement: .exact("0.1.22"))],
...
dependencies: [.package(product: "LSExtensions", type: .runtime)],

Now I can import Swift Package in my app.

Git Ignore

Derived/
*.xcodeproj
*.xcworkspace

Git remove

git rm --cached -r *.xcodeproj
git rm --cached -r *.xcworkspace

Build Time: after clean

I compared build speed with the initial project.

Before Tuist 9.4s

After 3.5s

Next article is setting up TCA!

If you found this post helpful, please give it a round of applause 👏. Explore more iOS-related content in my other posts.

For additional insights and updates, check out my LinkedIn profile. Thank you for your support!

Troubleshooting

bash: tuist: command not found

mise x — tuist

The target xxx has the following invalid source files globs

Check Package.swift’s directories are exist and correct.

No such module ‘ProjectDescriptionHelpers’

One of the paths in DEVELOPMENT_ASSET_PATHS does not exist: …/Preview Content

Edit .xcconfig file.

DEVELOPMENT_ASSET_PATHS="Resources/Preview Content"

References

--

--

Responses (1)