跳到内容

生成的文件

Tuist 可以在生成时创建文件和代码,从而简化 Xcode 项目的管理和开发工作。在本页中,你将了解这项功能以及如何在项目中使用它。

目标资源#

Xcode 项目支持向目标添加资源。然而,这会给团队带来一些挑战,尤其是在处理模块化项目时,因为源代码和资源经常会被移动:

  • 运行时访问不一致:资源在最终产品中的位置以及访问方式取决于目标的产品类型。例如,如果目标代表一个应用程序,资源会被复制到应用程序包中。这会导致访问资源的代码对包结构做出假设,这并不是理想的做法,因为它使代码更难理解,也不利于资源的迁移。
  • 不支持资源的产品类型:某些产品类型(如静态库)不是包,因此不支持资源。为此,你不得不改用其他产品类型,例如框架,但这可能会给项目或应用增加额外开销。例如,静态框架会静态链接到最终产品,并且需要一个构建阶段来仅将资源复制到最终产品中。或者使用动态框架,Xcode 会将二进制文件和资源都复制到最终产品中,但由于需要动态加载框架,这会增加应用的启动时间。
  • 容易出现运行时错误:资源通过名称和扩展名(字符串)进行标识。因此,任何拼写错误都会导致在尝试访问资源时出现运行时错误。这并不是理想的情况,因为这些错误无法在编译时被捕获,可能会导致发布版本崩溃。

Tuist 通过生成统一的接口来访问包和资源来解决上述问题,从而抽象掉实现细节。

推荐

虽然通过 Tuist 生成的接口访问资源并非强制要求,但我们推荐使用,因为它使代码更易于理解,也更方便资源的迁移。

资源#

Tuist 提供了在 Swift 中声明文件内容(如 Info.plist 或权限配置)的接口。这有助于确保目标和项目之间的一致性,并利用编译器在编译时捕获问题。你还可以创建自己的抽象来建模内容,并在目标和项目之间共享。

当你的项目生成时,Tuist 会合成这些文件的内容,并将它们写入相对于定义它们的项目目录的 Derived 目录中。

将 Derived 目录加入 Gitignore

我们建议将 Derived 目录添加到项目的 .gitignore 文件中。

包访问器#

Tuist 会生成一个接口,用于访问包含目标资源的包。

Swift#

目标将包含一个 Bundle 类型的扩展,用于暴露该包:

swift
let bundle = Bundle.module

Objective-C#

在 Objective-C 中,你将获得一个接口 {Target}Resources 来访问包:

objc
NSBundle *bundle = [MyFeatureResources bundle];
内部目标的限制

目前,Tuist 不会为仅包含 Objective-C 源代码的内部目标生成资源包访问器。这是一个已知限制,已在 issue #6456 中跟踪。

通过包支持库中的资源

如果目标产品(例如库)不支持资源,Tuist 会将资源包含在产品类型为 bundle 的目标中,以确保其被纳入最终产品,并且接口指向正确的包。这些生成的包会自动标记为 tuist:synthesized,并继承其父目标的所有标签,使你能够在 缓存配置中针对它们。

资源访问器#

资源通过字符串形式的名称和扩展名进行标识。这并不是理想的做法,因为这些错误无法在编译时被捕获,可能会导致发布版本崩溃。为了防止这种情况,Tuist 在项目生成过程中集成了 SwiftGen,以生成访问资源的接口。借此,你可以放心地访问资源,并利用编译器捕获任何问题。

Tuist 默认包含用于为以下资源类型生成访问器的 模板:

资源类型生成的文件
图片和颜色Assets+{Target}.swift
字符串Strings+{Target}.swift
Plist 文件{NameOfPlist}.swift
字体Fonts+{Target}.swift
文件Files+{Target}.swift

注意:你可以通过向项目选项传递 disableSynthesizedResourceAccessors 选项,按项目禁用资源访问器的生成。

自定义模板#

如果你想提供自己的模板来为其他资源类型生成访问器(必须由 SwiftGen 支持),你可以在 Tuist/ResourceSynthesizers/{name}.stencil 处创建它们,其中名称是资源名称的驼峰式版本。

资源模板名称
stringsStrings.stencil
assetsAssets.stencil
plistsPlists.stencil
fontsFonts.stencil
coreDataCoreData.stencil
interfaceBuilderInterfaceBuilder.stencil
jsonJSON.stencil
yamlYAML.stencil
filesFiles.stencil

如果你想配置要为其生成访问器的资源类型列表,可以使用 Project.resourceSynthesizers 属性并传入你要使用的资源合成器列表:

swift
let project = Project(resourceSynthesizers: [.string(), .fonts()])
参考

你可以查看 此示例,了解如何使用自定义模板为资源生成访问器。