Buildable Folder & Group & Folder Reference in Xcode

深入理解代替单纯记忆

问题背景

  • 在开发iOS项目时,希望将一堆图片资源放入Main Bundle中,但又不希望资源在Bundle的最顶层目录中,希望自定义目录
  • 但一时想不到该如何解决,于是想到Folder、Group等概念
  • 经过简单搜索后,发现Xcode对于这两个概念的定义还是有些差异的
  • 于是继续查阅学习了一番,编写本文,方便后续查阅和分享

本文提到的内容,参考的Xcode版本为26.0(17A324)和26.3(17C529)

Buildable Folder

  • Buildable Folder是自Xcode 16(2024年6月)引入的概念,初衷是为了减少代码管理中的冲突问题
  • 后续新建的工程或者新建Folder时,默认都是Buildable Folder

官方原文如下:

Minimize project file changes and avoid conflicts with buildable folder references. Convert an existing group to a buildable folder with the Convert to Folder context menu item in the Project Navigator. Buildable folders only record the folder path into the project file without enumerating the contained files, minimizing diffs to the project when your team adds or removes files, and avoiding source control conflicts. To use a folder as an opaque copiable resource, the default behavior before Xcode 16, uncheck the Build Folder Contents option in the File Inspector.

Buildable Folder如何降低代码冲突

  1. 先添加1个普通Group--BuildableFolderTest,project文件的变化如下所示:

  2. 然后向BuildableFolderTest Group中添加ABC.swift文件后,project文件的变化如下:

    这说明Group目录下的文件,都要在project文件中进行记录

  3. 继续,将BuildableFolderTest Group通过Convert to Folder选项转为Folder(Buildable Folder)后,project文件的变化如下:

  4. 然后再向BuildableFolderTest这个Folder中添加DEF.swift文件后,发现project文件没有任何变化

所以,project文件仅记录了Folder自身,至于目录中的文件是不会记录在project文件中,所以会减少因团队多人同时修改Project文件导致的代码冲突

Apply to Each File vs Apply Once to Folder

当创建Folder(Buildable Folder)后,选中Folder,在File inspector中会看到有个Build Rule,有两个选择:Apply to Each File和Apply Once to Folder,默认是Apply to Each File

Apply Once to Folder

Apply Once to Folder开启后,project文件是什么样?

当开启该模式时,通过查看目录下的每个文件可以看出,文件是没有Target归属的概念的。同样,在该目录下创建新文件也不需要选择Target

再配合Xcode Buildable Folders中所提到的To use a folder as an opaque copiable resource, the default behavior before Xcode 16, uncheck the Build Folder Contents option in the File Inspector.

其实,Apply Once to Folder就是Xcode 16之前的Folder,之前叫Folder Reference (在Xcode 16之前,创建Folder时,官方名称就叫做Folder Reference)

  • Folder Reference一般是用作资源包,目录下不包含源代码
  • 另一个Folder Reference重要作用是可以在Bundle中自定义目录

Buildable Folder vs Folder Reference

Buildable Folder顾名思义,其中的内容是由编译系统参与的

  • 所以Buildable Folder中可以放源代码文件,并可以参与编译,打包到最终可执行文件中;也可以制定源文件的Target
  • Folder Reference则保留老的逻辑,不参与编译,用作资源包,即使放入源代码文件也无法选择Target,只能当做普通文件资源处理

Create Group with Folder

同样是在Xcode 16开始的另一个变化是,创建Group时由原来的不自动创建磁盘物理目录(Folder)变为自动创建。当然,仍可以创建没有Folder的Group,原文如下:

Create groups with associated folders by default when using the New Group and New Group from Selection commands in the Project Navigator. To create a group without a folder, hold the Option key in the context menu to reveal the New Group without Folder variant of the command.

Group without Folder vs Group vs Folder(Buildable Folder) vs Folder Reference

特性 Group without Folder Group Buildable Folder Folder Reference
Project Navigator 图标
是否对应磁盘目录 ❌ 不必须 ✅ 必须 ✅ 必须 ✅ 必须
工程结构是否可与磁盘不同 ✅ 可以 ❌ 基本一致 ❌ 必须一致 ❌ 必须一致
.pbxproj 是否记录每个文件 ✅ 会 ✅ 会 ❌ 不会 ❌ 不会
新增文件是否修改 .pbxproj ✅ 会 ✅ 会 ❌ 不会 ❌ 不会
Git 冲突概率 高 高 低 低
是否参与编译系统 ✅ ✅ ✅ ❌
是否自动编译源码 ✅ ✅ ✅(自动发现目录中的源码) ❌
Bundle 中是否保留目录结构 ❌ 通常不会 ❌ 通常不会 ❌ 通常不会 会保留(如果被加入 Bundle)
默认是否进入 Bundle ❌ 否 ❌ 否 ❌ 否 仅在选中 Target 时自动加入
典型用途 逻辑分组 常规项目结构 源码目录 资源目录
  • 当前(Xcode 26),默认的Group和Folder组合是Group with Folder + Buildable Folder。这可能也意味着这两项是日常最常用的

回答开始的问题

  • 既然是想打包资源放入Bundle,并自定义目录,那必然是Folder Reference

参考

相关推荐
songgeb20 小时前
iOS App支持设置RTL语言的实践
ios·swift·ui kit
黑化旺仔2 天前
RunLoop 源码探索
ios·cocoa·xcode
2501_915106322 天前
KXApp 的 VS Code 真机调试:按下 Cmd+R 之后发生了什么
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2601_955518182 天前
36. 跨语言:C/C++与Swift&Objective-C混合编程(一)
objective-c·swift·c/c++·混合编程·跨语言
东坡肘子3 天前
谁是 AI-relay App 的真正威胁 -- 肘子的 Swift 周报 #158
人工智能·swiftui·swift
叫Guava不是瓜娃4 天前
我用 Swift 写了个本地语音输入:按住说话,松开就是整理好的文字(开源)
swift
Yannik5 天前
iOS Swift Package Manager(SPM)私有组件完整实操
ios·swift
我就是不信5 天前
Swift 方法派发机制详解
开发语言·ios·swift
2501_915918417 天前
在 Xcode 中运行和调试单元测试的完整指南
ide·vscode·macos·ios·单元测试·个人开发·xcode
茉莉玫瑰花茶7 天前
GO [ 标准库 · HTTP 高可用 ]
ios·iphone·xcode