👨🏻‍🏫 SwiftyLaunch Basics
Tuist Integration

SwiftyLaunch Tuist integration

SwiftyLaunch Basics - Tuist Integration

Starting with SwiftyLaunch 1.4, you have the ability to integrate Tuist right into your new SwiftyLaunch project.

You can enable Tuist to be included in your SwiftyLaunch projects by toggling it on in the SwiftyLaunch settings.

SwiftyLaunch Settings

What is Tuist?

Tuist is a toolchain that allows you to specify your Xcode project structure in a declarative way, making it easier to maintain, scale, and collaborate on your project. No more dealing with project.pbxproj merge conflicts!

You specify how your project should look in a declarative way, what targets are there, what their files are and how they are linked together.

Then, using just the Project.swift manifest file and the source code, Tuist can generate a new Xcode project for you.

Using Tuist

Generating the Xcode project

To use Tuist, first make sure that you have the Tuist CLI installed on your machine. We recommend using version 4.21.0 and higher. You can install it using Homebrew:

bash
brew tap tuist/tuist
brew install --formula tuist@4.21.1

Then, make sure you're in the your project folder (The one with Project.swift) and run the following command:

bash
tuist generate

This will generate an Xcode project for you and automatically open it in Xcode.

Now try deleting the Derived/ folder, the .xcodeproj file, and the .xcworkspace file, and run tuist generate again.

What you'll see is that Tuist will generate these files back again from scratch, using the information from the Project.swift file.

Tuist Generated Project

This means that now, you don't have to upload these files to your GitHub repository, and only upload the Project.swift manifest file together with your source code. Simply put the following in your .gitignore file and you're good to go:

.gitignore
Derived/
*.xcodeproj
*.xcworkspace
⚠️

Note, that after each generation, you will have to reselect the signing team in your Xcode UI. (At least the Project target and OneSignalNotificationServiceExtension target, if NotifKit is enabled)

Adjusting the Project.swift file

You can just open the Project.swift file and edit it there to your needs, but a recommended way would be to run the following command within your project folder:

tuist edit

This will open the Project.swift file in Xcode, and in comparison to simply opening it in a text editor, you'll get syntax highlighting and code completion. Here, you can specify your project structure, targets, and dependencies.

Common Workflows

Defining a new module

To add a new module (target) to your project, start off by creating a new function that adds the Module to the Project. This function will be run each time the project is generated.

Project.swift
func addMyModule() {
 
    // Module Name
    let targetName = "MyModule"
 
    // Defining the target
    let myModuleTarget: Target = .target(
        name: targetName,                                   // name, as specified above
        destinations: destinations,                         // destinations, defined globally
        product: .framework,                                // product type
        bundleId: "\(bundleID).\(targetName)",              // specified above
        deploymentTargets: .iOS(osVersion),                 // minimum deployment target, defined globally
        infoPlist: .default,                                // will use a default info.plist
        sources: ["Targets/\(targetName)/Sources/**"],      // sources folder
        // resources: ["Targets/\(targetName)/Resources/**"],  // resources folder
        dependencies: [                                     // included targets (packages, frameworks, modules)
            sharedKit,                                      // include SharedKit target
            // analyticsKit,                                // include AnalyticsKit target
            TargetDependency
                .package(product: "Alamofire", type: .runtime),  // include Alamofire target
        ]
    )
 
    // Add this module to the project as a target
    appDependencies.append(TargetDependency.target(name: targetName))
 
    // Add external package dependencies at project level
    // And include it in the target (see dependencies array in target definition)
    projectPackages
        .append(
            .remote(
                url: "https://github.com/Alamofire/Alamofire.git",
                requirement: .upToNextMajor(from: "5.9.1")
            )
        )
 
    // Add the target to the project
    projectTargets.append(myModuleTarget)
}

Adding the module to the project

To add the module to your project, call the previously defined function after the other calls to add modules, but before addApp():

Project.swift
// ... previous setup and module addition calls
 
addAIKit()
addAdsKit()
 
addMyModule()
 
addApp()
 
return Project( /* ... */ )
 
func addApp() { /* ... */ }
 
// ... other module definitions
 
func addMyModule() { /* ... */ }
 

When you generate the project again, you'll see the new module added to the project.

⚠️

Tuist will not add "Sources" and "Resources" and their subfolders to the project if they are empty. Make sure to add at least one file inside them.

Please refer to the Tuist documentation (opens in a new tab) for more information on how to use Tuist.