利用 Tuist 组织项目

通常,我们会直接使用 XCode 创建并管理项目。但是由于 XCode 的项目组织方式比较「原始」,存在几个问题:

  1. 项目管理用的 xcodeproj 是一个极为复杂的 XML,保存了项目中所有的文件及一个随机生成的 ID,在多用户协作或多分支开发的情况下(特别是存在同时创建文件)合并代码变得极为复杂且易错

  2. 对于 XCode 项目来说,文件系统中的文件与项目中的文件、文件系统中目录的名称与包的名称(甚至路径)可能并不一致,容易出现一些难以察觉的问题

  3. XCode 的编译系统将所有 Target 及 Framework 一起打包,这可能导致项目代码引用了未直接依赖的 Framework,造成本地编译通过但换一个新的环境(例如 CI 中)就失败了

因为这些问题的存在,业界出了许多不依赖 xcodeproj 的项目组织形式,如 XCodeGenBazel 等,但最终脱颖而出的是 Tuist

Tuist 利用 DSL 的方式(类似 Swift Package Manager)声明项目、利用文件系统管理项目文件,在需要时通过 tuist generate 命令生成 XCode Workspace,不将 xcodeproj / xcworkspace 文件提交到代码仓库中,可以说完全解决了 XCode 项目管理工具导致的缺陷。

因此,在本书中,将完全使用 Tuist 做项目管理。

本书中会假设你完全没用过 Tuist 而尽可能讲解所需要的全部内容;但本书毕竟不是《Tuist 从入门到精通》,多少会有些忽略的,而且也存在一些本书项目中没有使用的功能你可能感兴趣,因此还是建议你阅读下 Tuist 的 官方文档

安装 Tuist

安装 Tuist 十分简单,可以直接阅读官方文档:https://docs.tuist.dev/en/guides/quick-start/install-tuist 。简单来说,如果我们安装了 Homebrew,只要执行下面的两行命令即可将 Tuist 安装到本地:

brew tap tuist/tuist brew install --formula tuist

创建项目

打开终端,进入我们计划将项目存放的目录(例如 ~/Projects),然后在该目录下执行 tuist init,就会弹出交互式终端让你配置项目的信息。

就本书例子而言,我们进行如下配置:

  • 项目名:Novar

  • 平台:iOS

  • 是否启用缓存:否(这是一个带有免费额度的付费功能,如果你想使用,可以阅读官方文档了解)

tuist init 的过程中你可能会遇到类似如下的报错

Couldn't locate the root directory from path /opt/homebrew/Cellar/tuist@4.61.1/4.61.1/share/Templates/default. The root directory is the closest directory that contains a Tuist or a .git directory.

这是一个在某些环境下会出现的已知问题,临时解决方法(Workaround)是进入到提示的路径中的 share 目录下执行 git init 再重试

按照这个配置,Tuist 会在当前目录下创建 Novar 目录存放我们的项目。

进入该项目目录,执行

cd Novar # 进入项目目录 # Tuist 没有为我们的项目创建 git 仓库,我们手动创建一下以简化代码管理 git init git commit -A -m 'init' # 让 Tuist 为我们的项目生成 XCode Workspace 并在 XCode 中打开 tuist generate


然后试试看,在 XCode 中选择「Product → Run」( + R)运行(目标选择 iPhone 模拟器),等待运行成功后弹出 Hello World 就是成功了!

image-20250816-050109.png

了解项目结构

Novar ├── Derived │   ├── ... ├── Novar │   ├── Resources │   │   ├── ... │   ├── Sources │   │   ├── ContentView.swift │   │   └── NovarApp.swift │   └── Tests │   └── NovarTests.swift ├── Novar.xcodeproj ├── Novar.xcworkspace ├── Project.swift ├── Tuist │   └── Package.swift └── Tuist.swift

真机调试

在模拟器上运行完 app 那么下一步自然就是在真机上运行了。

[演示下如何在真机运行 App]

但是有一点必须要注意的是,Tuist 的项目配置是完全通过 Swift 完成的,这就意味着我们在 XCode 上的 Signing & Capabilities 中的修改会在下一次运行 tuist generate 时被复原 —— 我们必须在 tuist 的配置中修改 Development Team


settings: Settings.settings( base: ["DEVELOPMENT_TEAM": "ABCDE12345"] ),