☰
R.swift 资源忽略与生成器定制:用 `.rswiftignore` 和 `--generators` 精确控制资源生成
2026/9/25 4:05:21 网站建设 项目流程
  • 开发工具
  • 代码生成
  • CLI
  • 原生移动

【免费下载链接】R.swift

Strong typed, autocompleted resources like images, fonts and segues in Swift projects

项目地址:https://gitcode.com/gh_mirrors/rs/R.swift
点击查看免费下载

本文是 R.swift 资源控制机制的实战指南,聚焦两大核心能力:通过.rswiftignore文件精确排除项目中的问题资源,以及通过--generators参数只运行指定类型的资源生成器。读完本文,你将掌握.rswiftignore的完整语法(通配符、注释、!显式包含)、自定义 ignore 文件路径的 CLI 用法,以及如何在 Build Phase 中按需裁剪R.image、R.string、R.nib等生成结构,让 R.swift 的资源发现过程完全处于你的掌控之下。

为什么需要忽略资源

R.swift 会自动扫描项目中的资源(图片、字体、Storyboard、Strings 等)并为它们生成强类型的R结构。绝大多数情况下,自动发现开箱即用;但在少数情况下,某个文件可能给解析过程带来问题——例如文件命名中包含 Swift 关键字、文件格式无法被解析器识别、或者某些资源根本不想暴露在生成的 API 中。此时就需要忽略机制来"隔离"这些文件。

除了忽略单个资源文件,R.swift 还允许只运行部分生成器,从而跳过不需要的R.something结构,从源头减少生成代码的体积。

工作机制:.rswiftignore文件

在项目的 source root(源码根目录)下创建一个名为.rswiftignore的文件,R.swift 会自动发现并读取它。文件格式与.gitignore的模式语法 几乎相同:

  • *和**通配符均受支持;
  • 以#开头的行是注释;
  • 以!开头的模式用于显式包含某个或某类文件(即使它们被其他规则全局忽略了)。

注意:所有模式都是相对于.rswiftignore文件所在路径的文件路径,而不是相对于项目根目录或当前工作目录。

完整示例

官方文档给出的标准配置示例:

# Ignore a specific font file fonts/myspecialfont.ttf # Ignore all tiff and tif files in the images folder images/*.tif images/*.tiff # Ignore all strings files wherever they are **/*.strings # Ignore all files containing '.ignore.' **/*.ignore.* # Explicitly include a single file !keepme.ignore.png # Explicitly include all files containing '.keepme.' !**/*.keepme.*

逐条解读:

  • fonts/myspecialfont.ttf:精确忽略单个字体文件,路径相对.rswiftignore所在目录;
  • images/*.tif、images/*.tiff:匹配images目录下的所有 tif/tiff 图片,注意*不跨目录层级;
  • **/*.strings:**递归匹配任意层级的子目录,忽略项目中所有.strings文件;
  • **/*.ignore.*:忽略文件名中包含.ignore.的所有文件(不管在哪个目录层级);
  • !keepme.ignore.png:显式包含单个文件,即使它匹配了上面的**/*.ignore.*规则;
  • !**/*.keepme.*:显式包含所有文件名含.keepme.的文件。

规则匹配的底层逻辑

从源码看,IgnoreFile的解析与匹配逻辑非常清晰。读取文件后按换行拆分为候选模式,然后分两条流水线处理(IgnoreFile.swift):

  1. 忽略模式:过滤掉空行、注释行和!开头行,剩余模式展开成具体的文件 URL 列表,存入ignoredURLs;
  2. 显式包含模式:只取!开头的行,去掉首字符后同样展开成 URL 列表,存入explicitlyIncludedURLs。

最终的匹配判定(IgnoreFile.swift)是:

public func matches(url: URL) -> Bool { return ignoredURLs.contains(url) && !explicitlyIncludedURLs.contains(url) }

即先看是否被忽略规则命中,再看是否被显式包含规则豁免——两者同时成立时文件不被忽略。这保证了!规则具有比普通忽略规则更高的优先级。

判断哪些行算有效模式(IgnoreFile.swift)时,源码会先对每行做空白修剪:空行被丢弃;修剪后首字符为#的视为注释;首字符为!的视为显式包含模式。

模式展开底层依赖仓库内置的Glob实现(Glob.swift),默认采用GlobBehaviorBashV4行为(Glob.swift),即支持 globstar(**递归匹配)并包含 globstar 根目录下的文件。值得注意的是,Glob 默认黑名单了node_modules和Pods两个目录(Glob.swift),因此即使模式写得比较宽泛,这两个目录也不会被意外扫描。

忽略发生在哪个阶段

忽略过滤不是在生成代码时才执行,而是在资源解析阶段就完成了。在ProjectResources.parseXcodeproj中,从 Xcode 工程提取出所有资源路径后,会立即用 ignore 文件做一次过滤(ProjectResources.swift):

let urls = paths .map { $0.url(with: sourceTreeURLs.url(for:)) } .filter { !ignoreFile.matches(url: $0) }

也就是说,被忽略的资源根本不会进入后续的图片、字体、Strings 等解析器,自然也就不会出现在生成的R.generated.swift中。如果.rswiftignore文件缺失或读取失败,IgnoreFile会退化为一个空的 ignore 实例(不忽略任何文件),保证默认行为不受影响(ProjectResources.swift)。

仓库中的实证:IgnoreTests

官方示例工程Examples/ResourceApp中实际放置了Keep.dont.ignoreme.png、icon.ignoreme.png、hand.ignoreme.png、ExplicitInclude.ignoreme.png等文件名含.ignore.的资源,用于验证忽略规则。测试文件 IgnoreTests.swift 中:

func testExplicitInclude() { XCTAssertNotNil(R.image.keepDontIgnoreme()) }

验证了Keep.dont.ignoreme.png通过!显式包含规则被保留并生成为R.image.keepDontIgnoreme(),而其他.ignoreme文件被成功过滤掉。这直接印证了"忽略规则生效、!包含规则生效"两条路径在真实工程中的行为。

自定义 ignore 文件位置

默认情况下.rswiftignore必须位于 source root。如果你希望把 ignore 文件放在其他位置、或者使用不同的文件名,可以通过--rswiftignore标志显式指定路径:

rswift generate --rswiftignore config/ignore.list /path/to/R.generated.swift

从源码看,命令行选项的默认值正是.rswiftignore(App.swift),解析时会基于sourceRootURL拼接出最终的 ignore 文件 URL(App.swift):

let rswiftIgnoreURL = sourceTreeURLs.sourceRootURL .appendingPathComponent(globals.rswiftignore, isDirectory: false)

因此当你用--rswiftignore传入自定义路径时,该路径同样会相对于 source root 解析。

只运行特定生成器(排除 R.something)

默认情况下,R.swift 会运行全部生成器,为图片、nib、strings 等所有资源类型生成结构。在某些场景下(比如只想生成图片和字符串),可以通过--generators标志只运行指定类型:

rswift generate --generators image,string /path/to/R.generated.swift

多个生成器名称用逗号分隔。该标志通常加在 Build Phase 中调用 rswift 的命令行里,例如在 Xcode 的 Run Script 阶段配置:

可用生成器完整清单

官方文档列出的可用生成器如下:

生成器名称对应生成的 R 结构
imageR.image,图片资源
stringR.string,本地化字符串表
colorR.color,颜色资源
fileR.file,普通文件资源
fontR.font,字体资源
nibR.nib,nib/xib 视图
segueR.segue,segue 标识符
storyboardR.storyboard,storyboard 引用
reuseIdentifierR.reuseIdentifier,复用标识符
entitlementsR.entitlements,代码签名 entitlements
infoR.info,Info.plist 内容
idR.id,无障碍标识符(accessibility identifier)

需要补充说明的是,从源码看ResourceType枚举(ProjectResources.swift)实际定义了 14 种类型,除了上表 12 种之外还包括:

  • data:资产目录(Asset Catalog)中的 Data 资源,对应R.data;
  • project:工程级信息结构(包含开发语言与已知资源标签等)。

这两个生成器在当前仓库的 CLI 中同样可用,属于文档未列全而源码已实现的能力。

生成器过滤的底层实现

--generators参数的解析很简单:按逗号拆分后映射为ResourceType(App.swift)。当未传入任何生成器时,会回退为运行全部类型(App.swift):

generators: globals.generators.isEmpty ? ResourceType.allCases : globals.generators,

真正决定"哪个R.something出现"的逻辑在 RswiftCore.swift:生成器会逐一对每个结构做generators.contains(.xxx)判断,且要求对应解析结果非空才把该结构写进最终的R.generated.swift。例如字符串结构仅在generators.contains(.string)且stringStruct非空时生成。这意味着:

  1. 未列入--generators的类型,其解析器不会运行(见 ProjectResources.swift 中各处resourceTypes.contains(...)前置判断),解析开销也被省掉;
  2. 即使类型被列入,若项目中该类型资源为空,对应结构也会被跳过,生成的代码保持精简。

另外注意,font、nib、storyboard三个结构还参与了R结构中validate()方法的生成(RswiftCore.swift):只有当对应生成器开启且结构非空时,validate()中才会加入对应的校验行。

实战建议与常见误区

  • 优先用忽略而非删除文件:.rswiftignore不影响 Xcode 打包,被忽略的资源仍会随 App 分发,只是不进入强类型 API。适用于"文件必须存在但不想暴露"的场景。
  • !规则必须写在对应忽略规则之后才生效?从源码实现看,IgnoreFile并不区分规则先后顺序——它先把所有忽略模式展开成 URL 列表,再展开所有显式包含模式,匹配时做集合判定。因此!豁免不依赖书写顺序,这一点与部分 gitignore 实现略有差异。
  • 模式必须相对.rswiftignore文件:写绝对路径或相对项目根目录的路径都可能匹配不上,这是最常见的踩坑点。
  • 利用--generators收敛生成体积:如果只使用图片和字符串,--generators image,string能让生成的R.generated.swift更小、构建更快,也减少了无关 API 的暴露面。
  • 结合 Build Phase 使用:--generators与--rswiftignore都是 rswift 命令的全局选项(见 App.swift),可以直接拼接到 Build Phase 的 Run Script 中,与 R.swift 的自动发现机制共存。

小结

R.swift 的忽略与生成器定制机制,为资源发现提供了"减法"能力:.rswiftignore以类 gitignore 的语法、相对路径规则和!显式包含语义,在解析阶段精确过滤问题资源;--rswiftignore允许自定义 ignore 文件位置;--generators则从生成阶段按类型裁剪R结构。理解 IgnoreFile.swift 的集合匹配逻辑与 ProjectResources.swift 的解析期过滤流程,你就能在遇到异常资源文件、或希望精简生成 API 时,快速给出可复用的解决方案。

  • 开发工具
  • 代码生成
  • CLI
  • 原生移动

【免费下载链接】R.swift

Strong typed, autocompleted resources like images, fonts and segues in Swift projects

项目地址:https://gitcode.com/gh_mirrors/rs/R.swift
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询