.xcconfig — 什么是 .xcconfig、语法以及 Xcode 中的变量

作者: IT Sectr 发布日期: 2026-05-30 阅读时间: 8 分钟

.xcconfig 是一种 Xcode 配置文件,格式为 “键=值”,用于集中管理项目的 Build Settings。开发人员无需为每种配置手动修改 Xcode UI 中的参数,而是在文本文件中进行描述,从而实现版本控制并在项目间重用。根据 Apple Developer Documentation, 2025,使用 .xcconfig 可将项目配置时间缩短 70%,并消除开发人员之间的配置差异。.xcconfig 文件可以相互继承,形成配置链。

要点

  • .xcconfig — 一种包含 Build Settings 的文本文件,格式为键=值。
  • 继承 — 通过 #include 构建配置链(Dev → Staging → Production)。
  • 条件指令 — 平台(iOS/macOS)和架构的条件配置。
  • Build Settings — .xcconfig 中的设置会覆盖 Xcode 项目中的默认值。
  • 版本管理 — .xcconfig 与项目一起存储在 Git 的 xcshareddata 目录中。

什么是 .xcconfig?

.xcconfig(Xcode Configuration File)— 是一种纯文本文件,包含格式为 PARAMETER_NAME = value 的 Build Settings。.xcconfig 文件用于集中管理 Xcode 的构建配置:替代在 Build Settings UI 中手动编辑字段。每个 .xcconfig 绑定到一个 Build Configuration(Debug、Release)或整个项目,可以覆盖任何构建设置:SWIFT_VERSION、IPHONEOS_DEPLOYMENT_TARGET、PRODUCT_BUNDLE_IDENTIFIER、CODE_SIGN_STYLE、PROVISIONING_PROFILE_SPECIFIER。

在 .xcconfig 出现之前,构建设置仅存储在 project.pbxproj 中 — 这是一个难以在 diff 中阅读且无法添加注释的二进制/plist 文件。.xcconfig 解决了这个问题:开发人员可以为参数添加注释、按意义分组、为不同环境创建可版本化的文件以及在文件之间继承参数。这使得 .xcconfig 成为 iOS 项目配置管理的事实标准。

.xcconfig 文件位于项目内部,通常在 Configurations/BuildConfig/ 文件夹中。每个文件对应一个 Build Configuration:Debug.xcconfig、Release.xcconfig、Staging.xcconfig。此外,还会创建一个通用文件 Shared.xcconfig,通过 #include 连接到所有配置。这样就可以一次性定义通用参数,并在配置文件中覆盖特定参数。

相比 UI Build Settings 的优势

Diff 可读性:.xcconfig 的更改在 Git diff 中以普通行形式显示。相比之下,project.pbxproj 中字段顺序的变化会导致 diff 显示 50 行变更,而实际只修改了一个参数。注释:可以在 .xcconfig 中说明每个参数的用途。继承:可以创建包含通用设置的基础配置,并仅为 Debug 和 Release 覆盖必要的参数。

.xcconfig 的语法与结构

变量与替换

.xcconfig 的语法极其简单:每行是一个参数,名称和值通过等号分隔。= 周围的空格被忽略。值可以包含格式为 $(VARIABLE_NAME)${VARIABLE_NAME} 的变量。注释以 // 或 # 开头,直到行尾。行可以通过反斜杠 \ 延续到下一行。空行被忽略。

.xcconfig 中的变量可以引用其他变量,形成 复合值。例如:PRODUCT_NAME = MyAppPRODUCT_BUNDLE_IDENTIFIER = com.example.$(PRODUCT_NAME)。Xcode 在构建阶段计算值,替换变量的实际值。AGP 还支持系统变量:ARCHS、SDK_NAME、CONFIGURATION、PLATFORM_NAME,这些由构建环境设置。

条件配置使用方括号中的平台指令:PARAMETER[sdk=iphoneos*] = value。例如 SUPPORTED_PLATFORMS[sdk=iphoneos*] = iphoneos 仅为 iOS 构建设置参数。支持通配符:*(任意字符)、?(单个字符)。条件指令允许一个 .xcconfig 用于多个平台,并在同一文件中为 iOS 和 macOS 设置不同的值。

text
// Shared.xcconfig — 项目通用设置
SWIFT_VERSION = 5.0
IPHONEOS_DEPLOYMENT_TARGET = 16.0
SDKROOT = iphoneos
TARGETED_DEVICE_FAMILY = 1,2

// Bundle 标识符 — 由前缀和名称组成
BUNDLE_ID_PREFIX = com.example
PRODUCT_NAME = MyApp
PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME)

// macOS 的条件设置
SUPPORTED_PLATFORMS[sdk=macosx*] = macosx
PRODUCT_BUNDLE_IDENTIFIER[sdk=macosx*] = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME).mac

// 版本管理
MARKETING_VERSION = 2.4.1
CURRENT_PROJECT_VERSION = 37

通过 #include 继承配置

#include — 是 .xcconfig 的预处理器指令,用于引入另一个 .xcconfig 文件的内容。指令可以嵌套:Shared.xcconfig 可以 #include “Base.xcconfig”,Debug.xcconfig 可以 #include “Shared.xcconfig”。继承链允许构建配置层级,其中每一层覆盖前一层的参数。#include 遵循最后写入原则:如果同一参数在引入文件和主文件中都定义了,主文件中的值具有更高优先级。

典型 iOS 项目的正确层级:Base.xcconfig(最通用参数)→ Shared.xcconfig(项目设置)→ Debug.xcconfigRelease.xcconfig。Base.xcconfig 定义标准(SWIFT_VERSION、DEPLOYMENT_TARGET),Shared.xcconfig 定义项目特性(PRODUCT_NAME、PREPROCESSOR_DEFINITIONS),Debug/Release 定义环境(DEBUG_INFORMATION_FORMAT、OPTIMIZATION_CFLAGS)。#include 不允许循环依赖 — Xcode 在检测到循环时会报错。

示例:Config/Base.xcconfigConfig/iOS/Shared.xcconfigConfig/iOS/Debug.xcconfig。这种结构允许 iOS、macOS 和 tvOS 项目重用 Base,而 Shared 仅用于 iOS。注意:#include 使用文件名或相对于根 .xcconfig 位置的路径。不建议使用绝对路径 — 它们会在其他机器和 CI/CD 环境中破坏构建。

text
// --- Config/Base.xcconfig ---
SWIFT_VERSION = 5.0
ENABLE_MODULE_VERIFIER = YES
CLANG_ENABLE_MODULES = YES

// --- Config/iOS/Shared.xcconfig ---
#include "../Base.xcconfig"
IPHONEOS_DEPLOYMENT_TARGET = 16.0
PRODUCT_BUNDLE_IDENTIFIER = com.example.myapp

// --- Config/iOS/Debug.xcconfig ---
#include "Shared.xcconfig"
OPTIMIZATION_CFLAGS = -O0
DEBUG_INFORMATION_FORMAT = dwarf
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG
ENABLE_TESTABILITY = YES

// --- Config/iOS/Release.xcconfig ---
#include "Shared.xcconfig"
OPTIMIZATION_CFLAGS = -Osize
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
SWIFT_COMPILATION_MODE = wholemodule

在 Xcode 项目中连接 .xcconfig

项目级与目标级配置

Project Info → Configurations 中将 .xcconfig 连接到项目。对于每个 Build Configuration(Debug、Release、AdHoc),在下拉菜单 “Based on Configuration File” 中选择对应的 .xcconfig。如果配置未连接到文件,Xcode 使用 project.pbxproj 中的值。选择 .xcconfig 后,文件中的所有参数对该配置生效。

需要区分 Project-level(项目级)和 Target-level(目标级)配置。Project-level .xcconfig 为所有目标定义默认参数。Target-level .xcconfig 为特定目标覆盖这些参数。如果参数未在 target-level .xcconfig 中定义,则使用 project-level 的值。如果也未在那里定义,则使用 project.pbxproj 的值。实用规则:在 project-level 放置通用参数(构建、版本),在 target-level 放置目标特定设置(bundle identifier、provisioning)。

当 .xcconfig 和 UI Build Settings 冲突时,UI 中的值具有更高优先级(会覆盖 .xcconfig)。这可能导致混淆:开发人员在 UI 中修改 Build Setting,却不知道 .xcconfig 中指定了不同的值。建议 完全迁移到 .xcconfig,不要触碰 UI Build Settings。要检查实际应用的参数,请使用 xcrun xcodebuild -showBuildSettings — 该命令将显示所有级别解析后的最终参数值。

示例:Dev、Staging、Production 环境

我们来看一个三层配置:Dev(本地开发)、Staging(测试服务器)、Production(发布版本)。为每个环境创建单独的 .xcconfig,定义不同的 API_URL、日志记录和证书值。Dev 使用 localhost,Staging 使用 staging.api.example.com,Production 使用 api.example.com。三者都通过 #include 继承共用 Shared.xcconfig。

环境之间关键的区别参数是 PRODUCT_BUNDLE_IDENTIFIER。对于 Dev:com.example.myapp.dev,对于 Staging:com.example.myapp.staging,对于 Production:com.example.myapp。不同的 bundle ID 允许在同一设备上同时安装所有三个版本。此外,CODE_SIGN_IDENTITY(Dev 使用 Apple Development,Production 使用 Apple Distribution)和 PROVISIONING_PROFILE_SPECIFIER 也不同。

使用 INFOPLIST_PREFIX_HEADER 或带有 -D 预处理器的 OTHER_SWIFT_FLAGS 将值传递给代码。Swift 没有预处理器,因此使用 Active Compilation Conditions:SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEV。在代码中:#if DEV; #elseif STAGING; #else; #endif。对于 Objective-C 使用 GCC_PREPROCESSOR_DEFINITIONS。这使得无需修改源代码即可为不同环境编译不同的代码。

text
// --- Config/Dev.xcconfig ---
#include "Shared.xcconfig"

PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME).dev
CODE_SIGN_IDENTITY = Apple Development
PROVISIONING_PROFILE_SPECIFIER = Dev Profile

SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG DEV
OTHER_SWIFT_FLAGS = -D DEV

// API URL 通过 Info.plist — 值自动替换
API_BASE_URL = http://localhost:3000/api

// --- Config/Staging.xcconfig ---
#include "Shared.xcconfig"

PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME).staging
CODE_SIGN_IDENTITY = Apple Development
PROVISIONING_PROFILE_SPECIFIER = Staging Profile

SWIFT_ACTIVE_COMPILATION_CONDITIONS = STAGING
OTHER_SWIFT_FLAGS = -D STAGING
API_BASE_URL = https://staging.api.example.com/v2

// --- Config/Production.xcconfig ---
#include "Shared.xcconfig"

PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME)
CODE_SIGN_IDENTITY = Apple Distribution
PROVISIONING_PROFILE_SPECIFIER = AppStore Distribution

SWIFT_ACTIVE_COMPILATION_CONDITIONS = RELEASE
API_BASE_URL = https://api.example.com/v3

.xcconfig 与 Info.plist:值的传递

.xcconfig 中的值可以通过变量 $(PARAMETER_NAME) 传递到 Info.plist。如果参数在 .xcconfig 中定义(例如 API_BASE_URL),则可以在 Info.plist 中使用:<key>ApiBaseUrl</key><string>$(API_BASE_URL)</string>。在构建阶段,Xcode 将 $(API_BASE_URL) 替换为 .xcconfig 中的值。这使得无需修改代码即可配置应用程序 — 只需切换 Scheme。

用于 Info.plist 的 .xcconfig 参数必须是 公开的 — 它们会进入二进制文件并在反编译的应用程序中可见。对于机密值(令牌、密码)不要使用 .xcconfig — 应使用在服务器端运行的服务,如 Firebase Remote Config。.xcconfig 用于 Info.plist 适用于:服务器 URL、实体名称、跟踪器标识符、功能标志。

在代码中访问 Info.plist 的值:Bundle.main.object(forInfoDictionaryKey: “ApiBaseUrl”)(Objective-C/Swift)。如果值通过 .xcconfig 设置,它将被替换并可在 Bundle main.infoDictionary 中获取。此方法优于 BuildConfigField(如 Android 中),因为 Info.plist 是 iOS 的标准机制,其值可供所有系统组件使用,包括 extensions、widget 和 Siri Intents。

常见问题

.xcconfig 与 Xcode 中的 User-Defined Setting 有何区别?

User-Defined Setting 是通过 UI Build Settings 添加的自定义参数。它的工作方式与 .xcconfig 相同,但无法进行版本控制、添加注释以及在项目间重用。.xcconfig 是磁盘上的文件,而 User-Defined Setting 是 project.pbxproj 中的记录。

是否可以将 .xcconfig 用于 CocoaPods?

可以。CocoaPods 会为每个配置生成 Pods-*.xcconfig 文件。这些文件包含连接 pod 的设置。Pods.xcconfig 通过生成器文件中的 #include 自动连接到您的 .xcconfig。不要手动编辑 Pods.xcconfig — 它在 pod install 时会被覆盖。

如何在 Swift 代码中获取 .xcconfig 的值?

通过 Info.plist:在 .xcconfig 中定义参数,并在 Info.plist 中使用 $(PARAM)。在代码中:Bundle.main.infoDictionary[“PARAM”]。对于预处理器标志,使用 SWIFT_ACTIVE_COMPILATION_CONDITIONS#if CONDITION

为什么 .xcconfig 不生效?

可能的原因:您在 UI Build Settings 中修改了值(UI 会覆盖 .xcconfig);文件未连接到配置(请检查 Project → Info → Configurations);#include 路径错误;参数名称拼写错误。诊断:xcodebuild -showBuildSettings 将显示所有活跃参数。

SwiftUI 项目需要 .xcconfig 吗?

需要。.xcconfig 不依赖于 UI 框架。对于 SwiftUI 项目,.xcconfig 同样有用:管理 bundle ID、版本、环境配置、用于功能标志的 SWIFT_ACTIVE_COMPILATION_CONDITIONS。SwiftUI 不提供 .xcconfig 的替代方案,因此建议在任何项目中都使用它。

总结

  • .xcconfig — 用于可版本化管理 Xcode 配置的 Build Settings 文本文件。
  • 继承 — 通过 #include 构建从 Base 到 Production 的配置层级。
  • 语法 — 包括变量 $(VAR)、条件指令 [sdk=ios*] 以及 // 和 # 注释。
  • 连接 — 在 Project Info → Configurations 中为每个 Build Configuration 设置。
  • 环境 — Dev/Staging/Production 在 bundle ID、证书和 API URL 上有所不同。
  • Info.plist — 通过 $(PARAM) 从 .xcconfig 获取值,使其在运行时可用。
  • 建议:完全迁移到 .xcconfig,不要使用 UI Build Settings 以避免冲突。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读