.xcconfig — định nghĩa, cú pháp và biến trong Xcode

Tác giả: IT Sectr Đã đăng: 2026-05-30 Thời gian đọc: 8 phút

.xcconfig là tệp cấu hình Xcode ở định dạng “khóa=giá trị” quản lý tập trung Build Settings của dự án. Thay vì thay đổi tham số theo cách thủ công trong giao diện Xcode cho từng cấu hình, nhà phát triển mô tả chúng trong một tệp văn bản có thể quản lý phiên bản và tái sử dụng giữa các dự án. Theo Apple Developer Documentation, 2025, việc sử dụng .xcconfig giảm thời gian thiết lập dự án xuống 70% và loại bỏ sự khác biệt về cấu hình giữa các nhà phát triển. Các tệp .xcconfig có thể kế thừa lẫn nhau, tạo thành một chuỗi cấu hình.

Những điểm chính

  • .xcconfig — tệp văn bản chứa Build Settings ở định dạng khóa=giá trị.
  • Kế thừa qua #inherit cho phép xây dựng chuỗi cấu hình (Dev → Staging → Production).
  • Chỉ thị có điều kiện nền tảng (iOS/macOS) và kiến ​​trúc được quản lý qua cấu hình.
  • Build Settings trong .xcconfig ghi đè giá trị mặc định trong dự án Xcode.
  • Quản lý phiên bản — .xcconfig được lưu trong Git cùng với dự án trong xcshareddata.

.xcconfig là gì?

.xcconfig (Tệp cấu hình Xcode) là tệp văn bản thuần túy chứa Build Settings ở định dạng PARAMETER_NAME = value. Các tệp .xcconfig được sử dụng để quản lý tập trung cấu hình biên dịch Xcode: chúng thay thế việc chỉnh sửa thủ công các trường trong giao diện Build Settings. Mỗi .xcconfig được liên kết với một Build Configuration (Debug, Release) hoặc toàn bộ dự án và có thể ghi đè bất kỳ build setting nào: SWIFT_VERSION, IPHONEOS_DEPLOYMENT_TARGET, PRODUCT_BUNDLE_IDENTIFIER, CODE_SIGN_STYLE, PROVISIONING_PROFILE_SPECIFIER.

Trước khi .xcconfig xuất hiện, cài đặt biên dịch chỉ được lưu trong project.pbxproj — một tệp nhị phân/plist khó đọc trong diff và không thể chú thích. .xcconfig đã giải quyết vấn đề này: nhà phát triển có thể chú thích tham số, nhóm chúng theo ý nghĩa, tạo tệp có thể quản lý phiên bản cho các môi trường khác nhau và kế thừa tham số giữa các tệp. Điều này đã đưa .xcconfig trở thành tiêu chuẩn thực tế cho quản lý cấu hình trong các dự án iOS.

Các tệp .xcconfig nằm trong dự án, thường trong thư mục Configurations/ hoặc BuildConfig/. Mỗi tệp tương ứng với một Build Configuration: Debug.xcconfig, Release.xcconfig, Staging.xcconfig. Ngoài ra, một tệp Shared.xcconfig chung được tạo, được bao gồm trong tất cả các cấu hình qua #include. Điều này cho phép định nghĩa các tham số chung một lần và ghi đè các tham số cụ thể trong tệp cấu hình.

Lợi ích so với Build Settings giao diện

Khả năng đọc diff: các thay đổi trong .xcconfig hiển thị trong Git diff dưới dạng dòng thông thường. Không giống project.pbxproj, nơi thay đổi thứ tự trường hiển thị 50 dòng thay đổi cho một lần chỉnh sửa tham số. Chú thích: trong .xcconfig bạn có thể giải thích lý do cần mỗi tham số. Kế thừa: bạn có thể tạo cấu hình cơ sở với cài đặt chung và chỉ ghi đè các tham số cần thiết cho Debug và Release.

Cú pháp và cấu trúc của .xcconfig

Biến và thay thế

Cú pháp .xcconfig đơn giản nhất có thể: mỗi dòng là một tham số, tên và giá trị được phân tách bằng dấu bằng. Khoảng trắng xung quanh = bị bỏ qua. Giá trị có thể chứa biến ở định dạng $(VARIABLE_NAME) hoặc ${VARIABLE_NAME}. Chú thích bắt đầu bằng // hoặc # và áp dụng đến cuối dòng. Dòng tiếp tục ở dòng tiếp theo bằng dấu gạch chéo ngược \. Các dòng trống bị bỏ qua.

Các biến trong .xcconfig có thể tham chiếu đến các biến khác, tạo giá trị tổng hợp. Ví dụ: PRODUCT_NAME = MyApp, PRODUCT_BUNDLE_IDENTIFIER = com.example.$(PRODUCT_NAME). Xcode đánh giá giá trị tại thời điểm biên dịch, thay thế các giá trị thực của biến. AGP cũng hỗ trợ các biến hệ thống: ARCHS, SDK_NAME, CONFIGURATION, PLATFORM_NAME, được đặt bởi môi trường biên dịch.

Để cấu hình có điều kiện, các chỉ thị nền tảng trong dấu ngoặc vuông được sử dụng: PARAMETER[sdk=iphoneos*] = value. Ví dụ: SUPPORTED_PLATFORMS[sdk=iphoneos*] = iphoneos đặt tham số chỉ cho bản dựng iOS. Ký tự đại diện được hỗ trợ: * (bất kỳ ký tự nào), ? (một ký tự). Chỉ thị có điều kiện cho phép có một .xcconfig cho nhiều nền tảng và đặt giá trị khác nhau cho iOS và macOS trong một tệp.

text
// Shared.xcconfig — cài đặt chung của dự án
SWIFT_VERSION = 5.0
IPHONEOS_DEPLOYMENT_TARGET = 16.0
SDKROOT = iphoneos
TARGETED_DEVICE_FAMILY = 1,2

// Định danh bundle — được tạo từ tiền tố và tên
BUNDLE_ID_PREFIX = com.example
PRODUCT_NAME = MyApp
PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME)

// Cài đặt có điều kiện cho macOS
SUPPORTED_PLATFORMS[sdk=macosx*] = macosx
PRODUCT_BUNDLE_IDENTIFIER[sdk=macosx*] = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME).mac

// Quản lý phiên bản
MARKETING_VERSION = 2.4.1
CURRENT_PROJECT_VERSION = 37

Kế thừa cấu hình qua #include

#include là chỉ thị tiền xử lý .xcconfig bao gồm nội dung của tệp .xcconfig khác. Các chỉ thị có thể lồng nhau: Shared.xcconfig có thể #include “Base.xcconfig”, Debug.xcconfig có thể #include “Shared.xcconfig”. Chuỗi kế thừa cho phép xây dựng hệ thống phân cấp cấu hình, nơi mỗi cấp ghi đè tham số của cấp trước. #include hoạt động theo nguyên tắc ghi sau: nếu cùng một tham số được định nghĩa trong cả tệp được bao gồm và tệp chính, giá trị từ tệp chính được ưu tiên.

Hệ thống phân cấp chính xác cho một dự án iOS điển hình: Base.xcconfig (các tham số chung nhất) → Shared.xcconfig (cài đặt dự án) → Debug.xcconfig hoặc Release.xcconfig. Base.xcconfig định nghĩa các tiêu chuẩn (SWIFT_VERSION, DEPLOYMENT_TARGET), Shared.xcconfig — các đặc thù dự án (PRODUCT_NAME, PREPROCESSOR_DEFINITIONS), Debug/Release — môi trường (DEBUG_INFORMATION_FORMAT, OPTIMIZATION_CFLAGS). #include không cho phép chu trình — Xcode sẽ báo lỗi nếu phát hiện phụ thuộc vòng.

Ví dụ: Config/Base.xcconfigConfig/iOS/Shared.xcconfigConfig/iOS/Debug.xcconfig. Cấu trúc này cho phép tái sử dụng Base cho các dự án iOS, macOS và tvOS, và Shared chỉ cho iOS. Lưu ý: #include sử dụng tên tệp hoặc đường dẫn tương đối từ vị trí của .xcconfig gốc. Đường dẫn tuyệt đối không được khuyến nghị — chúng làm hỏng bản dựng trên các máy khác và trong 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

Kết nối .xcconfig trong dự án Xcode

Cấu hình cấp dự án và cấp target

Kết nối .xcconfig với dự án được thực hiện trong Project Info → Configurations. Đối với mỗi Build Configuration (Debug, Release, AdHoc), .xcconfig tương ứng được chọn từ trình đơn thả xuống “Based on Configuration File”. Nếu một cấu hình không được liên kết với tệp, Xcode sử dụng giá trị từ project.pbxproj. Sau khi chọn .xcconfig, tất cả các tham số từ tệp trở nên hoạt động cho cấu hình đó.

Điều quan trọng là phân biệt cấu hình cấp dự án và cấp target. .xcconfig cấp dự án đặt tham số mặc định cho tất cả các target. .xcconfig cấp target ghi đè chúng cho một target cụ thể. Nếu một tham số không được đặt trong .xcconfig cấp target, giá trị từ cấp dự án được sử dụng. Nếu cũng không được đặt ở đó, giá trị từ project.pbxproj được sử dụng. Quy tắc thực tế: đặt tham số chung (biên dịch, phiên bản) ở cấp dự án và các đặc thù target (định danh bundle, provisioning) ở cấp target.

Khi có xung đột giữa .xcconfig và Build Settings giao diện, giá trị từ giao diện được ưu tiên (nó ghi đè .xcconfig). Điều này có thể gây nhầm lẫn: nhà phát triển thay đổi Build Setting trong giao diện mà không biết rằng .xcconfig chỉ định một giá trị khác. Khuyến nghị chuyển hoàn toàn sang .xcconfig và không chạm vào Build Settings giao diện. Để kiểm tra tham số nào đang được áp dụng, sử dụng xcrun xcodebuild -showBuildSettings — lệnh sẽ hiển thị giá trị cuối cùng của tất cả tham số sau khi giải quyết tất cả các cấp.

Ví dụ: môi trường Dev, Staging, Production

Hãy xem xét cấu hình ba cấp: Dev (phát triển cục bộ), Staging (máy chủ thử nghiệm), Production (phát hành). Một .xcconfig riêng được tạo cho mỗi môi trường, định nghĩa các giá trị API_URL, ghi nhật ký và chứng chỉ khác nhau. Dev sử dụng localhost, Staging sử dụng staging.api.example.com, Production sử dụng api.example.com. Cả ba kế thừa Shared.xcconfig chung qua #include.

Tham số chính khác nhau giữa các môi trường là PRODUCT_BUNDLE_IDENTIFIER. Đối với Dev: com.example.myapp.dev, đối với Staging: com.example.myapp.staging, đối với Production: com.example.myapp. Các bundle ID khác nhau cho phép cài đặt cả ba phiên bản trên một thiết bị cùng lúc. CODE_SIGN_IDENTITY (Apple Development cho Dev, Apple Distribution cho Production) và PROVISIONING_PROFILE_SPECIFIER cũng khác nhau.

Để truyền giá trị vào mã, INFOPLIST_PREFIX_HEADER hoặc OTHER_SWIFT_FLAGS với bộ tiền xử lý -D được sử dụng. Swift không có bộ tiền xử lý, vì vậy Active Compilation Conditions được sử dụng: SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEV. Trong mã: #if DEV; #elseif STAGING; #else; #endif. Đối với Objective-C, GCC_PREPROCESSOR_DEFINITIONS được sử dụng. Điều này cho phép biên dịch mã khác nhau cho các môi trường khác nhau mà không thay đổi tệp nguồn.

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

// URL API qua Info.plist — giá trị được thay thế
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 và Info.plist: truyền giá trị

Các giá trị từ .xcconfig có thể được truyền vào Info.plist qua biến $(PARAMETER_NAME). Nếu một tham số được định nghĩa trong .xcconfig (ví dụ: API_BASE_URL), nó có thể được sử dụng trong Info.plist: <key>ApiBaseUrl</key><string>$(API_BASE_URL)</string>. Tại thời điểm biên dịch, Xcode thay thế $(API_BASE_URL) bằng giá trị từ .xcconfig. Điều này cho phép cấu hình ứng dụng mà không thay đổi mã — chỉ cần chuyển đổi sơ đồ.

Các tham số .xcconfig được sử dụng trong Info.plist phải là công khai — chúng nằm trong tệp nhị phân và hiển thị trong ứng dụng đã được dịch ngược. Không sử dụng .xcconfig cho các giá trị bí mật (token, mật khẩu) — hãy sử dụng các dịch vụ như Firebase Remote Config, chạy trên máy chủ. .xcconfig cho Info.plist phù hợp cho: URL máy chủ, tên thực thể, định danh trình theo dõi, feature flags.

Truy cập giá trị Info.plist trong mã: Bundle.main.object(forInfoDictionaryKey: “ApiBaseUrl”) cho Objective-C/Swift. Nếu giá trị được đặt qua .xcconfig, nó sẽ được thay thế và có sẵn trong Bundle main.infoDictionary. Phương pháp này được ưa chuộng hơn BuildConfigField (như trong Android) vì Info.plist là cơ chế tiêu chuẩn của iOS và các giá trị của nó có sẵn cho tất cả các thành phần hệ thống, bao gồm extensions, widgets và Siri Intents.

Câu hỏi thường gặp

.xcconfig khác User-Defined Setting trong Xcode như thế nào?

User-Defined Setting là tham số tùy chỉnh được thêm qua giao diện Build Settings. Nó hoạt động giống .xcconfig, nhưng không thể quản lý phiên bản, chú thích hoặc tái sử dụng giữa các dự án. .xcconfig là tệp trên đĩa, User-Defined Setting là mục nhập trong project.pbxproj.

Có thể sử dụng .xcconfig cho CocoaPods không?

Có, CocoaPods tạo các tệp Pods-*.xcconfig cho mỗi cấu hình. Các tệp này chứa cài đặt để kết nối các pod. Pods.xcconfig tự động được liên kết với .xcconfig của bạn qua #include trong tệp tạo. Không chỉnh sửa Pods.xcconfig thủ công — nó bị ghi đè khi pod install.

Làm thế nào để lấy giá trị .xcconfig trong mã Swift?

Qua Info.plist: định nghĩa tham số trong .xcconfig và sử dụng $(PARAM) trong Info.plist. Trong mã: Bundle.main.infoDictionary[“PARAM”]. Đối với cờ tiền xử lý, sử dụng SWIFT_ACTIVE_COMPILATION_CONDITIONS#if CONDITION.

Tại sao .xcconfig không được áp dụng?

Nguyên nhân: bạn đã thay đổi giá trị trong Build Settings giao diện (giao diện ghi đè .xcconfig); tệp không được liên kết với cấu hình (kiểm tra Project → Info → Configurations); đường dẫn #include sai; lỗi chính tả trong tên tham số. Chẩn đoán: xcodebuild -showBuildSettings sẽ hiển thị tất cả các tham số đang hoạt động.

Có cần .xcconfig cho dự án SwiftUI không?

Có, .xcconfig không phụ thuộc vào framework giao diện. Đối với dự án SwiftUI, .xcconfig hữu ích tương tự: quản lý bundle ID, phiên bản, cấu hình môi trường, SWIFT_ACTIVE_COMPILATION_CONDITIONS cho feature flags. SwiftUI không cung cấp thay thế cho .xcconfig, do đó khuyến nghị sử dụng nó với bất kỳ dự án nào.

Tổng kết

  • .xcconfig — tệp văn bản để quản lý Build Settings có thể quản lý phiên bản trong Xcode.
  • Kế thừa qua #include cho phép xây dựng hệ thống phân cấp cấu hình từ Base đến Production.
  • Cú pháp bao gồm biến $(VAR), chỉ thị có điều kiện [sdk=ios*] và chú thích // và #.
  • Kết nối được thực hiện trong Project Info → Configurations cho mỗi Build Configuration.
  • Môi trường Dev/Staging/Production khác nhau bởi bundle ID, chứng chỉ và URL API.
  • Info.plist nhận giá trị từ .xcconfig qua $(PARAM), làm cho chúng có sẵn tại thời gian chạy.
  • Khuyến nghị: chuyển hoàn toàn sang .xcconfig và tránh sử dụng Build Settings giao diện để ngăn xung đột.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm