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

参考

相关推荐
AC赳赳老秦16 小时前
数据采集全链路审计留痕:用 OpenClaw 实现合规审计与追溯
开发语言·汇编·python·php·swift·deepseek·openclaw
传奇开心果编程21 小时前
【SwiftUI入门练中学】第17课 通知与后台任务
学习·ui·ios·swiftui·swift
yqj2341 天前
ESP32-S3中小智项目优化内容
ide·macos·xcode
逐流人2 天前
Ceph对象存储与文件系统存储管理:从RADOS网关、S3与Swift到CephFS快照同步
linux·运维·ceph·云原生·云计算·swift·rados
传奇开心果编程3 天前
【SwiftUI入门练中学】第7课 动画与手势:让界面更灵动
学习·macos·ui·ios·swiftui·swift
传奇开心果编程3 天前
【SwiftUI娓娓道来】第3课:让界面活起来——交互与动画指南
学习·macos·ui·ios·swiftui·swift
用户38034165882974 天前
控制中心一键后台录音:我被自己的 Spike 骗了两次
ios·swift
东坡肘子4 天前
iPhone Duo 留给开发者的一个月 -- 肘子的 Swift 周报 #155
人工智能·swiftui·swift
茶底世界之下5 天前
导出进度不是一个百分比:AVFoundation 收尾阶段的状态建模
ios·swift