Buildable Folder & Group & Folder Reference in Xcode

深入理解代替单纯记忆

问题背景

  • 在开发iOS项目时,希望将一堆图片资源放入Main Bundle中,但又不希望资源在Bundle的最顶层目录中,希望自定义目录
  • 但一时想不到该如何解决,于是想到FolderGroup等概念
  • 经过简单搜索后,发现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 FileApply 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)变为自动创建。当然,仍可以创建没有FolderGroup,原文如下:

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

参考

相关推荐
2501_915106327 小时前
不依赖 Xcode 的 iOS 编译器,kxapp 中 kxbuild 工具详解
ide·vscode·ios·cocoa·个人开发·xcode·敏捷流程
Lucas_coding8 小时前
【语音相关】Opus编码器生命周期管理:从“有噪音“到“无噪音“的完美转换 [opus, pcm 转化电流音问题解决]
macos·xcode·pcm
2501_916008891 天前
iOS开发者工具有哪些?Xcode、Fastlane 与 kxapp 的组合使用
ide·vscode·macos·ios·个人开发·xcode·敏捷流程
房开民1 天前
http服务端 mongoose常用api
网络协议·http·xcode
报错小能手2 天前
ios开发方向——对于实习开发的app(Robopocket)讲解
开发语言·学习·ios·swift
茶底世界之下2 天前
Harbeth:高性能Metal图像处理库,让你的图片处理速度飞起来!
前端·github·swift
风舞雪凌月2 天前
【趣谈】移动系统和桌面系统编程语言思考
java·c语言·c++·python·学习·objective-c·swift
UXbot3 天前
AI App 设计生成工具哪个好?
ui·kotlin·软件构建·产品经理·ai编程·swift
黄林晴3 天前
Swift 杀进 Android,Google 和 Apple 都要失眠了?
android·前端·swift