合成文件
合成文件 {#synthesized-files}
Section titled “合成文件 {#synthesized-files}”Tuist 可以在生成时生成文件和代码,为管理和使用 Xcode 项目带来一些便利。在本页中,你将了解此功能以及如何在项目中使用它。
Target 资源 {#target-resources}
Section titled “Target 资源 {#target-resources}”Xcode 项目支持向 target 添加资源。但是,它们给团队带来了一些挑战,尤其是在处理模块化项目时,源代码和资源经常被移动:
- 不一致的运行时访问:资源在最终产品中的位置以及如何访问它们取决于 target 产品。例如,如果你的 target 代表一个应用,资源会被复制到应用 bundle 中。这导致访问资源的代码对 bundle 结构做出假设,这不理想,因为它使代码更难理解,资源也难以移动。
- 不支持资源的产品:某些产品(如静态库)不是 bundle,因此不支持资源。因此,你必须使用不同的产品类型,例如框架,这可能会给你的项目或应用带来一些开销。例如,静态框架将静态链接到最终产品,并且需要一个构建阶段才能将资源仅复制到最终产品。或者对于动态框架,Xcode 会将二进制文件和资源都复制到最终产品,但会增加应用的启动时间,因为框架需要动态加载。
- 容易出现运行时错误:资源通过其名称和扩展名(字符串)来标识。因此,任何一个中的拼写错误都会导致尝试访问资源时出现运行时错误。这不理想,因为它不会在编译时被捕获,并可能导致发布版本崩溃。
Tuist 通过合成统一的 bundle 和资源访问接口来解决上述问题,抽象了实现细节。
::: warning 推荐 虽然通过 Tuist 合成的接口访问资源不是强制的,但我们推荐使用它,因为它使代码更容易理解,资源更容易移动。 :::
资源 {#resources}
Section titled “资源 {#resources}”Tuist 提供了用 Swift 声明 Info.plist 或 entitlements 等文件内容的接口。这对于确保跨 target 和项目的一致性以及利用编译器在编译时捕获问题很有帮助。你也可以提出自己的抽象来建模内容并在 target 和项目之间共享。
当你的项目被生成时,Tuist 会合成这些文件的内容并将它们写入相对于定义它们的项目目录的 Derived 目录。
::: tip 将 DERIVED 目录加入 GITIGNORE
我们建议将项目的 Derived 目录添加到 .gitignore 文件中。
:::
Bundle 访问器 {#bundle-accessors}
Section titled “Bundle 访问器 {#bundle-accessors}”Tuist 合成一个访问包含 target 资源的 bundle 的接口。
Swift {#swift}
Section titled “Swift {#swift}”target 将包含一个 Bundle 类型的扩展来暴露 bundle:
let bundle = Bundle.moduleObjective-C {#objectivec}
Section titled “Objective-C {#objectivec}”在 Objective-C 中,你将获得一个 {Target}Resources 接口来访问 bundle:
NSBundle *bundle = [MyFeatureResources bundle];::: warning 内部 TARGET 的限制 目前,Tuist 不会为仅包含 Objective-C 源代码的内部 target 生成资源 bundle 访问器。这是 issue #6456 中跟踪的已知限制。 :::
::: tip 通过 BUNDLES 支持库中的资源
如果 target 产品(例如库)不支持资源,Tuist 会将资源包含在产品类型为 bundle 的 target 中,确保它最终出现在最终产品中,并且接口指向正确的 bundle。这些合成的 bundle 会自动标记为 tuist:synthesized 并继承其父 target 的所有标签,允许你在
资源访问器 {#resource-accessors}
Section titled “资源访问器 {#resource-accessors}”资源通过其名称和扩展名使用字符串来标识。这不理想,因为它不会在编译时被捕获,并可能导致发布版本崩溃。为了防止这种情况,Tuist 将 SwiftGen 集成到项目生成过程中,以合成访问资源的接口。借助这一点,你可以放心地访问资源,利用编译器来捕获任何问题。
Tuist 默认包含模板来合成以下资源类型的访问器:
| 资源类型 | 合成的文件 |
|---|---|
| 图片和颜色 | Assets+{Target}.swift |
| 字符串 | Strings+{Target}.swift |
| 属性列表 | {NameOfPlist}.swift |
| 字体 | Fonts+{Target}.swift |
| 文件 | Files+{Target}.swift |
注意:你可以通过将
disableSynthesizedResourceAccessors选项传递给项目选项来禁用每个项目合成资源访问器。
自定义模板 {#custom-templates}
Section titled “自定义模板 {#custom-templates}”如果你想提供自己的模板来合成对其他资源类型的访问器,这些资源类型必须由 SwiftGen 支持,你可以在 Tuist/ResourceSynthesizers/{name}.stencil 处创建它们,其中名称是资源的小驼峰命名版本。
| 资源 | 模板名称 |
|---|---|
| strings | Strings.stencil |
| assets | Assets.stencil |
| plists | Plists.stencil |
| fonts | Fonts.stencil |
| coreData | CoreData.stencil |
| interfaceBuilder | InterfaceBuilder.stencil |
| json | JSON.stencil |
| yaml | YAML.stencil |
| files | Files.stencil |
如果你想配置要合成访问器的资源类型列表,可以使用 Project.resourceSynthesizers 属性,传入你想使用的资源合成器列表:
let project = Project(resourceSynthesizers: [.string(), .fonts()])::: info 参考 你可以在此示例中查看如何使用自定义模板合成资源访问器的示例。 :::